home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
User's Choice Windows CD
/
User's Choice Windows CD (CMS Software)(1993).iso
/
utility2
/
wincmd.zip
/
WINCMC.ZIP
/
WINCMD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-07
|
118KB
|
3,669 lines
//===========================================================
// WINCMD - A command language interpeter for Windows
// Copyright (C) 1993 Douglas Boling
//===========================================================
// Returns no. of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
#define VARBUFFSIZE 42000
#define TOKBUFFSIZE 65500
#define MAXLINELEN 256
#define MAXSTRLEN 252
#define MAXOUTLINES 100
#define MAXLIBS 32
//-----------------------------------------------------------
// Include flags for WINDOWS.H
//-----------------------------------------------------------
#define NOCOMM 1 Comm driver APIs and definitions
#define NOMINMAX 1 min() and max() macros
#define NOLOGERROR 1 LogError() and related definitions
#define NOPROFILER 1 Profiler APIs
#define NORESOURCE 1 Resource management
#define NOATOM 1 Atom management
#define NOLANGUAGE 1 Character test routines
#define NODBCS 1 Double-byte character set routines
#define NOGDICAPMASKS 1 GDI device capability constants
#define NODRAWTEXT 1 DrawText() and related definitions
#define NOTEXTMETRIC 1 TEXTMETRIC and related APIs
#define NOSCALABLEFONT 1 Truetype scalable font support
#define NOBITMAP 1 Bitmap support
#define NORASTEROPS 1 GDI Raster operation definitions
#define NOMETAFILE 1 Metafile support
#define NOSYSTEMPARAMSINFO 1 SystemParametersInfo() and SPI_#define definitions
#define NODEFERWINDOWPOS 1 DeferWindowPos and related definitions
#define NOKEYSTATES 1 MK_* message key state flags
#define NOWH 1 SetWindowsHook and related WH_* definitions
#define NOSCROLL 1 Scrolling APIs and scroll bar control
//#define NOVIRTUALKEYCODES 1 VK_* virtual key codes
//#define NOMENUS 1 Menu APIs
//#define NOKEYBOARDINFO 1 Keyboard driver routines
//#define NOCOLOR 1 COLOR_#define color values
//#define NOGDIOBJ 1 GDI pens, brushes, fonts
//#define NOMSG 1 APIs and definitions that use MSG structure
//#define NOWINSTYLES 1 Window style definitions
//-----------------------------------------------------------
// Include files
//-----------------------------------------------------------
#include "windows.h"
#include "commdlg.h"
#include "stdlib.h"
#include "direct.h"
#include "dos.h"
#include "string.h"
#include "WinCmd.h"
// Message handler functions
LONG DoCreateMain (HWND, UINT, UINT, LONG);
LONG DoSizeMain (HWND, UINT, UINT, LONG);
LONG DoTimerMain (HWND, UINT, UINT, LONG);
LONG DoInitMenuMain (HWND, UINT, UINT, LONG);
LONG DoDestroyMain (HWND, UINT, UINT, LONG);
LONG DoCommandMain (HWND, UINT, UINT, LONG);
LONG DoRefreshMain (HWND, UINT, UINT, LONG);
// Menu Function Prototypes
//LONG DoMainCtlExit (HWND, UINT, HWND, UINT);
LONG DoMainMenuFileOpen (HWND, UINT, HWND, UINT);
LONG DoMainMenuFileLoad (HWND, UINT, HWND, UINT);
LONG DoMainMenuFileExit (HWND, UINT, HWND, UINT);
LONG DoMainMenuShowList (HWND, UINT, HWND, UINT);
LONG DoMainMenuShowOut (HWND, UINT, HWND, UINT);
LONG DoMainMenuClearOut (HWND, UINT, HWND, UINT);
LONG DoMainMenuMinOnRun (HWND, UINT, HWND, UINT);
LONG DoMainMenuAbout (HWND, UINT, HWND, UINT);
// Control function Prototypes
LONG DoMainCtlRun (HWND, UINT, HWND, UINT);
LONG DoMainCtlStep (HWND, UINT, HWND, UINT);
LONG DoMainCtlReset (HWND, UINT, HWND, UINT);
// Utility function prototpes
BOOL MyYield (void);
BOOL MyGetFilename (HWND, char *, INT, char *, INT);
//------------------------------------------------------------
// Message dispatch table for MainWindowProc
//------------------------------------------------------------
struct decodeUINT MainMessages[] = {
WM_COMMAND, DoCommandMain,
WM_CREATE, DoCreateMain,
WM_SIZE, DoSizeMain,
WM_TIMER, DoTimerMain,
WM_INITMENU, DoInitMenuMain,
MYMSG_REFRESH, DoRefreshMain,
WM_DESTROY, DoDestroyMain} ;
//------------------------------------------------------------
// Command Message dispatch for MainWindowProc
//------------------------------------------------------------
struct decodeCMD MainMenuItems[] = {
IDD_RUN, DoMainCtlRun,
IDD_STEP, DoMainCtlStep,
IDD_RESET, DoMainCtlReset,
IDM_OPEN, DoMainMenuFileOpen,
IDM_LOAD, DoMainMenuFileLoad,
IDM_EXIT, DoMainMenuFileExit,
IDM_SHOWLIST, DoMainMenuShowList,
IDM_SHOWOUT, DoMainMenuShowOut,
IDM_CLEAROUT, DoMainMenuClearOut,
IDM_MINONRUN, DoMainMenuMinOnRun,
IDM_ABOUT, DoMainMenuAbout} ;
//-----------------------------------------------------------
// Application specific function prototypes
//-----------------------------------------------------------
INT InitInterpeter (HWND);
INT ResetInterpeter (HWND);
INT TermInterpeter (void);
INT ParseCmdLine (LPSTR);
void WriteOutput (HWND, char *);
void PrintError (HWND, INT, INT, BOOL);
INT LoadProgram (HWND, HANDLE *, LPLINETOKEN, UINT);
INT TokenizeLine (LPSTR *, LPLINETOKEN *, UINT);
INT AddTokenInit (char *, BYTE, UINT, DWORD);
PTOKEN AddToken (char *, BYTE, UINT, DWORD, INT *);
PTOKEN AddTokenL (LPSTR, BYTE, UINT, DWORD, LPINT);
INT SetToken (PTOKEN, BYTE, UINT, DWORD);
//LPTOKEN CALLBACK AddTokenExt ( LPSTR, BYTE, UINT, DWORD, LPINT);
DWORD CALLBACK TokFuncCallback (INT, LPTOKEN, LPSTR, BYTE, UINT, DWORD);
LONG ComputeNum (LPSTR *, INT *);
INT GetOp (LPLINETOKEN *, PTOKEN, UINT *, INT);
INT Eval (LPLINETOKEN *, PTOKEN, INT);
LONG Eval2Num (LPLINETOKEN *, INT, INT *);
INT ExecuteLine (LPLINETOKEN *, INT);
INT Execute (LPLINETOKEN *, INT);
LONG GetTokenVal (PTOKEN);
LPSTR GetTokenStringL (PTOKEN);
char *GetTokenString (PTOKEN);
INT ResolveLine (LPLINETOKEN *, LPSTR, INT);
INT ReadFile (char *, HANDLE *);
INT StuffKeyString (char **);
INT LocalOpCPren (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpAdd (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpSub (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpMul (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpDiv (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpCmp (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpNOT (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpNOTBits (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpAND (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpANDBits (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpOR (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpORBits (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpXOR (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpXORBits (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpLThan (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpLEThan (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpGThan (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpGEThan (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpNotEqual (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalComma (LPLINETOKEN *, PTOKEN, PTOKEN);
INT LocalOpOPren (LPLINETOKEN *, PTOKEN);
INT LocalLENGTH (LPLINETOKEN *, PTOKEN);
INT LocalUPPER (LPLINETOKEN *, PTOKEN);
INT LocalSUBSTR (LPLINETOKEN *, PTOKEN);
INT LocalARG (LPLINETOKEN *, PTOKEN);
INT LocalWAIT (LPLINETOKEN *, PTOKEN);
INT WinActivate (LPLINETOKEN *, PTOKEN);
INT WinSendKeys (LPLINETOKEN *, PTOKEN);
INT WinGetActWin (LPLINETOKEN *, PTOKEN);
INT WinGetNextWin (LPLINETOKEN *, PTOKEN);
INT WinGetWinEXE (LPLINETOKEN *, PTOKEN);
INT WinMsgBox (LPLINETOKEN *, PTOKEN);
INT WinAskBox (LPLINETOKEN *, PTOKEN);
INT WinTicks (LPLINETOKEN *, PTOKEN);
INT LocalIF (LPLINETOKEN *, INT);
INT LocalThenElse (LPLINETOKEN *, INT);
INT LocalDO (LPLINETOKEN *, INT);
INT LocalEND (LPLINETOKEN *, INT);
INT LocalWHILE (LPLINETOKEN *, INT);
INT LocalSAY (LPLINETOKEN *, INT);
INT LocalLaunch (LPLINETOKEN *, INT);
INT LocalAssign (LPLINETOKEN *, INT);
INT LocalEXIT (LPLINETOKEN *, INT);
INT LocalRETURN (LPLINETOKEN *, INT);
INT LocalLEAVE (LPLINETOKEN *, INT);
INT LocalChDir (LPLINETOKEN *, INT);
INT LocalCMT2EOL (LPLINETOKEN *, INT);
//-----------------------------------------------------------
// Global data
//-----------------------------------------------------------
HANDLE hInst;
HWND hMain, hwndLList, hwndOList;
HWND hwndStepBtn, hwndRunBtn, hwndResetBtn;
BOOL bMinOnRun = FALSE;
BOOL bShowOut = FALSE;
BOOL bShowList = TRUE;
char *pszAskAns;
char szAppName[] = "WinCmd"; // Application name
char szTitleText[] = "WinCmd Window"; // Window text
char szMenuName[] = "WinCmdMenu"; // Menu name
char szIconName[] = "WinCmdIcon"; // Icon name
char szProfileName[] = "WinCmd.ini"; // INI file name
LOCALOP OpList[] = {
// Name Type Level Function
{")", TTYPE_CPAREN, 1, LocalOpCPren},
{"NOT", TTYPE_LUOP, 15, LocalOpNOT},
{"NOTB",TTYPE_LUOP, 15, LocalOpNOTBits},
{"*", TTYPE_LOP, 14, LocalOpMul},
{"/", TTYPE_LOP, 14, LocalOpDiv},
{"+", TTYPE_LOP, 13, LocalOpAdd},
{"-", TTYPE_LUOP, 13, LocalOpSub},
{"<", TTYPE_LOP, 11, LocalOpLThan},
{"<=", TTYPE_LOP, 11, LocalOpLEThan},
{">", TTYPE_LOP, 11, LocalOpGThan},
{">=", TTYPE_LOP, 11, LocalOpGEThan},
{"=", TTYPE_ASSIGN_CMP, 10, LocalOpCmp},
{"==", TTYPE_LOP, 10, LocalOpCmp},
{"<>", TTYPE_LOP, 10, LocalOpNotEqual},
{"ANDB",TTYPE_LOP, 9, LocalOpANDBits},
{"XORB",TTYPE_LOP, 8, LocalOpXORBits},
{"ORB", TTYPE_LOP, 7, LocalOpORBits},
{"AND", TTYPE_LOP, 6, LocalOpAND},
{"OR", TTYPE_LOP, 5, LocalOpOR},
{"XOR", TTYPE_LOP, 5, LocalOpXOR},
{",", TTYPE_BREAK, 1, LocalComma},
};
LOCALFUNC FuncList[] = {
// Name Type Function
{"(", TTYPE_OPAREN, LocalOpOPren},
{"LENGTH", TTYPE_LOCALFUNC, LocalLENGTH},
{"UCASE", TTYPE_LOCALFUNC, LocalUPPER},
{"SUBSTR", TTYPE_LOCALFUNC, LocalSUBSTR},
{"ARG", TTYPE_LOCALFUNC, LocalARG},
{"DELAY", TTYPE_LOCALFUNC, LocalWAIT},
{"APPACTIVATE", TTYPE_LOCALFUNC, WinActivate},
{"GETAPPACTIVE", TTYPE_LOCALFUNC, WinGetActWin},
{"GETAPPEXE", TTYPE_LOCALFUNC, WinGetWinEXE},
{"GETNEXTAPP", TTYPE_LOCALFUNC, WinGetNextWin},
{"SENDKEYS", TTYPE_LOCALFUNC, WinSendKeys},
{"MSGBOX", TTYPE_LOCALFUNC, WinMsgBox},
{"ASKBOX", TTYPE_LOCALFUNC, WinAskBox},
{"TICKS", TTYPE_LOCALFUNC, WinTicks},
};
LOCALSTATEMENT StatementList[] = {
// Name Type Function
{"WHILE", TTYPE_LSTATEMENT, LocalWHILE},
{"IF", TTYPE_LSTATEMENT, LocalIF},
{"THEN", TTYPE_THENELSE, LocalThenElse},
{"ELSE", TTYPE_THENELSE, LocalThenElse},
{"DO", TTYPE_LSTATEMENT, LocalDO},
{"END", TTYPE_LSTATEMENT, LocalEND},
{"EXIT", TTYPE_LSTATEMENT, LocalEXIT},
{"RETURN", TTYPE_LSTATEMENT, LocalRETURN},
{"LEAVE", TTYPE_LSTATEMENT, LocalLEAVE},
{"PRINT", TTYPE_LSTATEMENT, LocalSAY},
{"SAY", TTYPE_LSTATEMENT, LocalSAY},
{"CD", TTYPE_LSTATEMENT, LocalChDir},
{"CHDIR", TTYPE_LSTATEMENT, LocalChDir},
{"REM", TTYPE_CMT2EOL, LocalCMT2EOL},
{"//", TTYPE_CMT2EOL, LocalCMT2EOL},
{"'", TTYPE_CMT2EOL, LocalCMT2EOL},
};
//
// Table for DOS Internal Commands
//
struct {
char *szName;
} CmdList[] = {
// "name----"
{"MD"}, //DOS internal commands
// {"CD"},
{"RD"},
{"CLS"},
{"DIR"},
{"DEL"},
{"REN"},
{"VER"},
{"VOL"},
{"CTTY"},
{"CHCP"},
{"TYPE"},
{"COPY"},
{"DATE"},
{"TIME"},
{"ERASE"},
// {"CHDIR"},
{"MKDIR"},
{"RMDIR"},
{"BREAK"},
{"RENAME"},
{"DELETE"},
{"VERIFY"},
{"TRUENAME"},
};
struct {
char *szName;
BYTE ucKey;
} SKList[] = {
// "name----" Key
{"bksp", VK_BACK},
{"break", VK_CANCEL},
{"capslock", VK_CAPITAL},
{"clear", VK_CLEAR},
{"delete", VK_DELETE},
{"down", VK_DOWN},
{"end" , VK_END},
{"enter", VK_RETURN},
{"esc", VK_ESCAPE},
{"help", VK_HELP},
{"home", VK_HOME},
{"insert", VK_INSERT},
{"left", VK_LEFT},
{"numlock", VK_NUMLOCK},
{"pgdn", VK_NEXT},
{"pgup", VK_PRIOR},
{"prtsc", VK_SNAPSHOT},
{"pause", VK_PAUSE},
{"right", VK_RIGHT},
{"tab", VK_TAB},
{"up", VK_UP},
{"scroll", VK_SCROLL},
{"F1", VK_F1},
{"F2", VK_F2},
{"F3", VK_F3},
{"F4", VK_F4},
{"F5", VK_F5},
{"F6", VK_F6},
{"F7", VK_F7},
{"F8", VK_F8},
{"F9", VK_F9},
{"F0", VK_F10},
{"F11", VK_F11},
{"F12", VK_F12},
{"F13", VK_F13},
{"F14", VK_F14},
{"F15", VK_F15},
{"F16", VK_F16},
{"F17", VK_F17},
{"F18", VK_F18},
{"F19", VK_F19},
{"F20", VK_F20},
{"F21", VK_F21},
{"F22", VK_F22},
{"F23", VK_F23},
{"F24", VK_F24},
};
PTOKEN ptVarList;
UINT wVarCount;
PBYTE pbVarBuff, pbVarStrings;
LPBYTE lpbTokBuff, lpbTokLine;
HANDLE hTokBuff, hVarBuff, hFileBuff = 0;
INT sLibCount = 0;
FARPROC lpfnLibFunc[MAXLIBS];
HINSTANCE hLib[MAXLIBS];
FARPROC lpfnTokenFuncCallback;
char szNull[]= "";
char szProgName[12] = "";
char szCmdBuff[128] = "";
char szProgExt[40] = "";
char szTemp[33];
BOOL bRunning = FALSE;
BOOL bHold = FALSE;
BOOL bProg =TRUE;
BOOL bAutoStart = FALSE;
BOOL bAtEnd = FALSE;
UINT wCurrentLine;
INT sFinalRC = 0;
UINT hWaitTimer;
//============================================================
// WinMain -- entry point for this application from Windows.
//============================================================
INT APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpCmdLine, INT nCmdShow) {
MSG msg;
INT rc;
hInst = hInstance;
//
// If first instance, perform any init processing
//
if(!hPrevInstance)
if((rc = InitApp(hInstance)) != 0)
return rc;
//
// Initialize this instance
//
if((rc = InitInstance(hInstance, lpCmdLine, nCmdShow)) != 0)
return rc;
//
// Application message loop
//
bProg = TRUE;
while (bProg) {
if (bHold) {
bProg = GetMessage (&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
//Execute Line has a yield call in it
rc = ExecuteLine (&(LPLINETOKEN)lpbTokLine, FUNC_EXECUTE);
if (rc) {
bRunning = FALSE;
bHold = TRUE;
if (rc == RC_END_OF_PROGRAM) {
bAtEnd = TRUE;
if (bAutoStart)
PostMessage (hMain, WM_QUIT, 0, 0);
else
PostMessage (hMain, MYMSG_REFRESH, 0, 0);
} else
PrintError (hMain, wCurrentLine, rc, TRUE);
}
if (rc == ERR_UNEXP_PROGTERM)
bProg = FALSE;
}
}
//
// Instance cleanup
//
return TermInstance(hInstance, sFinalRC);
}
//-----------------------------------------------------------
// InitApp - Global initialization code for this application.
//-----------------------------------------------------------
INT InitApp(HANDLE hInstance) {
WNDCLASS wc;
//
// Register App Window class
//
wc.style = 0; // Window style
wc.lpfnWndProc = MainWndProc; // Callback function
wc.cbClsExtra = 0; // Extra class data
wc.cbWndExtra = 0; // Extra window data
wc.hInstance = hInstance; // Owner handle
wc.hIcon = LoadIcon(hInst, szIconName); // Application icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor
wc.hbrBackground = COLOR_WINDOW + 1; // Background color
wc.lpszMenuName = szMenuName; // Menu name
wc.lpszClassName = szAppName; // Window class name
if (RegisterClass(&wc) == 0)
return 1;
return 0;
}
//-----------------------------------------------------------
// InitInstance - Instance initialization code for this app.
//-----------------------------------------------------------
INT InitInstance(HANDLE hInstance, LPSTR lpCmdLine, INT nCmdShow) {
int x,y, Cx, Cy, rc = 0;
char szErrorStr[50];
x = GetPrivateProfileInt (szAppName, PRO_XPOS, CW_USEDEFAULT,
szProfileName);
y = GetPrivateProfileInt (szAppName, PRO_YPOS, CW_USEDEFAULT,
szProfileName);
Cx = GetPrivateProfileInt (szAppName, PRO_XSIZE, CW_USEDEFAULT,
szProfileName);
Cy = GetPrivateProfileInt (szAppName, PRO_YSIZE, CW_USEDEFAULT,
szProfileName);
GetProfileString ("Windows", "Programs", "com exe pif bat",
szProgExt, sizeof (szProgExt));
hMain = CreateWindow( // create frame window
szAppName, // window class name
szTitleText, // text for title bar
WS_OVERLAPPEDWINDOW, // window style
x, y, // default position
Cx, Cy, // default size
NULL, // no parent window
NULL, // use class default menu
hInstance, // window owner
NULL); // ptr to creation data
if(!hMain) return 0x10;
lpfnTokenFuncCallback = MakeProcInstance ((FARPROC) TokFuncCallback, hInstance);
rc = ParseCmdLine (lpCmdLine);
if (rc) {
if (rc > 0)
rc += 11;
else
rc = abs (rc);
if (LoadString (hInst, rc, szErrorStr, sizeof (szErrorStr)) == 0) {
itoa (rc, szTemp, 10);
strcpy (szErrorStr, "Error number: ");
strcat (szErrorStr, szTemp);
}
MessageBox (hMain, szErrorStr, szAppName, MB_OK | MB_ICONHAND);
return 0;
}
rc = InitInterpeter (hMain);
if (rc) {
if (rc > 0)
rc += 11;
else
rc = abs (rc);
if (LoadString (hInst, rc, szErrorStr, sizeof (szErrorStr)) == 0) {
itoa (rc, szTemp, 10);
strcpy (szErrorStr, "Error number: ");
strcat (szErrorStr, szTemp);
}
MessageBox (hMain, szErrorStr, szAppName, MB_OK | MB_ICONHAND);
return rc;
}
if (bAutoStart)
ShowWindow(hMain, nCmdShow | SW_SHOW | SW_MINIMIZE);
else
ShowWindow(hMain, nCmdShow | SW_SHOW);
UpdateWindow(hMain); // force WM_PAINT message
return 0; // return success flag
}
//------------------------------------------------------------
// TermInstance - Instance termination code for this app.
//------------------------------------------------------------
INT TermInstance(HANDLE hinstance, int sDefRC) {
TermInterpeter ();
return sDefRC;
}
//============================================================
// Message handling procedures for MainWindow
//============================================================
//------------------------------------------------------------
// MainWndProc - Callback function for application window
//------------------------------------------------------------
LONG CALLBACK MainWndProc(HWND hWnd, UINT wMsg, UINT wParam,
LONG lParam) {
INT i;
//
// Search message list to see if we need to handle this
// message. If in list, call procedure.
//
for(i = 0; i < dim(MainMessages); i++) {
if(wMsg == MainMessages[i].Code)
return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//------------------------------------------------------------
// GetLListPos - Computes the position of the source listbox
//------------------------------------------------------------
void GetLListPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, UINT *fFlags){
RECT rect;
INT sWinHeight, sWinWidth;
GetClientRect (hWnd, &rect);
sWinHeight = rect.bottom - rect.top;
sWinWidth = rect.right - rect.left;
if (bShowList)
*fFlags = SWP_SHOWWINDOW;
else
*fFlags = SWP_HIDEWINDOW;
*x = 10;
*Cx = sWinWidth - 90;
if (bShowOut) {
*y = sWinHeight/2 + 10;
*Cy = sWinHeight/2 - 10;
} else {
*y = 10;
*Cy = sWinHeight - 10;
}
return;
}
//------------------------------------------------------------
// GetOListPos - Computes the position of the source listbox
//------------------------------------------------------------
void GetOListPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, UINT *fFlags){
RECT rect;
INT sWinHeight, sWinWidth;
GetClientRect (hWnd, &rect);
sWinHeight = rect.bottom - rect.top;
sWinWidth = rect.right - rect.left;
if (bShowOut)
*fFlags = SWP_SHOWWINDOW;
else
*fFlags = SWP_HIDEWINDOW;
*x = 10;
*y = 10;
*Cx = sWinWidth - 90;
if (bShowList)
*Cy = sWinHeight/2 - 10;
else
*Cy = sWinHeight - 10;
return;
}
//------------------------------------------------------------
// GetBtnPos - Computes the position of the buttons
//------------------------------------------------------------
void GetBtnPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, INT sNum) {
RECT rect;
INT sWinHeight, sWinWidth;
GetClientRect (hWnd, &rect);
sWinHeight = rect.bottom - rect.top;
sWinWidth = rect.right - rect.left;
*x = sWinWidth - 75;
*y = 30 + (35 * sNum);
*Cx = 70;
*Cy = 30;
return;
}
//------------------------------------------------------------
// DoCreateMain - process WM_CREATE message for frame window.
//------------------------------------------------------------
LONG DoCreateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
DWORD dwStyle;
INT x,y,Cx,Cy;
UINT fFlags;
RECT rect;
INT sWinWidth;
GetClientRect (hWnd, &rect);
sWinWidth = rect.right - rect.left;
//Create Child Windows
GetLListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
if (bShowList)
dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
else
dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL |
LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
hwndLList = CreateWindow ("listbox", NULL, dwStyle,
x, y, // Pos
Cx, Cy, // Size
hWnd, //Parent handle
IDD_LINELIST, //ID number
hInst, NULL);
SendDlgItemMessage (hWnd, IDD_LINELIST, LB_SETTABSTOPS, 1,
(LPARAM)(LPINT)&x);
GetOListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
if (bShowOut)
dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
else
dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL |
LBS_NOTIFY | LBS_DISABLENOSCROLL;
hwndOList = CreateWindow ("listbox", NULL, dwStyle,
x, y, // Pos
Cx, Cy, // Size
hWnd, //Parent handle
IDD_OUTLIST, //ID number
hInst, NULL);
x = 14;
SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_SETTABSTOPS, 1,
(LPARAM)(LPINT)&x);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 0);
hwndRunBtn = CreateWindow ("button", "Run",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x, y, // Pos
Cx, Cy, // Size
hWnd, //Parent handle
IDD_RUN, //ID number
hInst, NULL);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 1);
hwndStepBtn = CreateWindow ("button", "Step",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x, y, // Pos
Cx, Cy, // Size
hWnd, //Parent handle
IDD_STEP, //ID number
hInst, NULL);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 2);
hwndResetBtn = CreateWindow ("button", "Reset",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
x, y, // Pos
Cx, Cy, // Size
hWnd, //Parent handle
IDD_RESET, //ID number
hInst, NULL);
return 0;
}
//------------------------------------------------------------
// DoSizeMain - process WM_SIZE message for frame window.
//------------------------------------------------------------
LONG DoSizeMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoTimerMain - process WM_TIMER message for frame window.
//------------------------------------------------------------
LONG DoTimerMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
if (wParam == WAITTIMER_ID) {
bHold = FALSE;
KillTimer (hWnd, hWaitTimer);
}
return 0;
}
//------------------------------------------------------------
// DoInitMenuMain - process WM_INITMENU message
//------------------------------------------------------------
LONG DoInitMenuMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
if (bShowList)
CheckMenuItem (GetMenu(hWnd), IDM_SHOWLIST,
MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem (GetMenu(hWnd), IDM_SHOWLIST,
MF_BYCOMMAND | MF_UNCHECKED);
if (bShowOut)
CheckMenuItem (GetMenu(hWnd), IDM_SHOWOUT,
MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem (GetMenu(hWnd), IDM_SHOWOUT,
MF_BYCOMMAND | MF_UNCHECKED);
if (bMinOnRun)
CheckMenuItem (GetMenu(hWnd), IDM_MINONRUN,
MF_BYCOMMAND | MF_CHECKED);
else
CheckMenuItem (GetMenu(hWnd), IDM_MINONRUN,
MF_BYCOMMAND | MF_UNCHECKED);
return 0;
}
//------------------------------------------------------------
// DoRefreshMain - Refresh main windows. This procedure
// is called by the user defined MYMSG_REFRESH message
//------------------------------------------------------------
LONG DoRefreshMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
INT x,y,Cx,Cy;
UINT fFlags;
GetLListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
SetWindowPos (hwndLList, 0, x, y, Cx, Cy, fFlags);
GetOListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
SetWindowPos (hwndOList, 0, x, y, Cx, Cy, fFlags);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 0);
SetWindowPos (hwndRunBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 1);
SetWindowPos (hwndStepBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 2);
SetWindowPos (hwndResetBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
if (szCmdBuff[0] == 0) {
EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
EnableWindow (GetDlgItem (hWnd, IDD_RESET), FALSE);
SetDlgItemText (hWnd, IDD_RUN, "Run");
EnableWindow (GetDlgItem (hWnd, IDD_RUN), FALSE);
} else {
if (bRunning) {
EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
EnableWindow (GetDlgItem (hWnd, IDD_RESET), FALSE);
SetDlgItemText (hWnd, IDD_RUN, "Stop");
} else {
SetDlgItemText (hWnd, IDD_RUN, "Run");
EnableWindow (GetDlgItem (hWnd, IDD_RESET), TRUE);
if (bAtEnd)
EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
else
EnableWindow (GetDlgItem (hWnd, IDD_STEP), TRUE);
}
EnableWindow (GetDlgItem (hWnd, IDD_RUN), TRUE);
}
SendDlgItemMessage (hMain, IDD_LINELIST, LB_SETCURSEL, wCurrentLine, 0);
return 0;
}
//------------------------------------------------------------
// DoCommandMain - process WM_COMMAND message for frame window
// by decoding the menubar item with the menuitems[] array,
// then running the corresponding function to process the command.
//------------------------------------------------------------
LONG DoCommandMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
INT i;
UINT idItem, wNotifyCode;
HWND hwndCtl;
idItem = (UINT) wParam; // Parse Parameters
hwndCtl = (HWND) LOWORD(lParam);
wNotifyCode = (UINT) HIWORD(lParam);
//
// Call routine to handle control message
//
for(i = 0; i < dim(MainMenuItems); i++) {
if(idItem == MainMenuItems[i].Code)
return (*MainMenuItems[i].Fxn)(hWnd, idItem, hwndCtl,
wNotifyCode);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
//------------------------------------------------------------
// DoDestroyMain - process WM_DESTROY message for frame window.
//------------------------------------------------------------
LONG DoDestroyMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
RECT rect;
if (hFileBuff)
GlobalFree (hFileBuff);
bRunning = FALSE;
bHold = TRUE;
//Save Window position
if (!IsIconic (hWnd) && !IsZoomed (hWnd)) {
GetWindowRect (hWnd, &rect);
MyWritePrivateProfileInt (szAppName, PRO_XPOS, rect.left,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_YPOS, rect.top,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_XSIZE,
rect.right - rect.left,
10, szProfileName);
MyWritePrivateProfileInt (szAppName, PRO_YSIZE,
rect.bottom - rect.top,
10, szProfileName);
}
PostQuitMessage (0);
return 0;
}
//============================================================
// Control handling procedures for MainWindow
//============================================================
//------------------------------------------------------------
// DoMainCtlRun - Process Run button
//------------------------------------------------------------
LONG DoMainCtlRun (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
if (bRunning) {
bRunning = FALSE;
bShowList = TRUE;
bHold = TRUE;
} else {
if (!bAtEnd) {
bRunning = TRUE;
bHold = FALSE;
bShowList = FALSE;
bShowOut = TRUE;
if (bMinOnRun)
ShowWindow (hWnd, SW_SHOWMINIMIZED);
}
else
return 0;
}
SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoMainCtlStep - Process Step button
//------------------------------------------------------------
LONG DoMainCtlStep (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
bHold = FALSE;
return 0;
}
//------------------------------------------------------------
// DoMainCtlReset - Process Reset button
//------------------------------------------------------------
LONG DoMainCtlReset (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
INT sRC;
if (bRunning)
return 0;
sRC = ResetInterpeter (hWnd);
if (sRC)
PrintError (hWnd, 0, sRC, TRUE);
else {
bShowList = TRUE;
bShowOut = FALSE;
}
SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
return 0;
}
//============================================================
// Menu handling procedures for MainWindow
//============================================================
//------------------------------------------------------------
// DoMainMenuFileOpen - Process File/Open menu item
//------------------------------------------------------------
LONG DoMainMenuFileOpen (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
int sRC;
static char *szFilter[] = {"WinCmd Files (*.WCM)", "*.WCM",
"All Files (*.*)", "*.*", "" };
MyGetFilename (hWnd, szCmdBuff, sizeof (szCmdBuff)-1, *szFilter, 1);
szCmdBuff[strlen (szCmdBuff)+1] = 0;
sRC = ResetInterpeter (hWnd);
if (sRC)
PrintError (hWnd, 0, sRC, TRUE);
else {
bShowList = TRUE;
bShowOut = FALSE;
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuFileLoad - Process File/Load Lib menu item
//------------------------------------------------------------
LONG DoMainMenuFileLoad (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
static char *szFilter[] = {"Libraries (*.dll)", "*.DLL",
"All Files (*.*)", "*.*", "" };
char szLibName[128];
int sRC;
FARPROC lpfnLibLoad;
if (sLibCount == MAXLIBS)
return 0;
MyGetFilename (hWnd, szLibName, sizeof (szLibName), *szFilter, 1);
hLib[sLibCount] = LoadLibrary (szLibName);
if (hLib[sLibCount] < 32) {
PrintError (hWnd, 0, ERR_LAUNCH_ERR - sRC, TRUE);
return 0;
}
lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibLoad");
if (lpfnLibLoad == 0) {
FreeLibrary (hLib[sLibCount]);
PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
return 0;
}
sRC = ((LPLIBLOAD)*lpfnLibLoad) (hWnd, sLibCount, ERR_LIBERROR_START - sLibCount);
if (sRC) {
PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
FreeLibrary (hLib[sLibCount]);
return 0;
}
lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
if (lpfnLibLoad == 0) {
PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
FreeLibrary (hLib[sLibCount]);
return 0;
}
lpfnLibFunc[sLibCount] = lpfnLibLoad;
sLibCount++;
sRC = ResetInterpeter (hWnd);
if (sRC)
PrintError (hWnd, 0, sRC, TRUE);
else {
bShowList = TRUE;
bShowOut = FALSE;
}
return 0;
}
//------------------------------------------------------------
// DoMainMenuShowList - Process View/Show Listing menu item
//------------------------------------------------------------
LONG DoMainMenuShowList (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
if (bShowList)
bShowList = FALSE;
else
bShowList = TRUE;
SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoMainMenuShowOut - Process View/Show Output menu item
//------------------------------------------------------------
LONG DoMainMenuShowOut (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
if (bShowOut)
bShowOut = FALSE;
else
bShowOut = TRUE;
SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoMainMenuClearOut - Process View/Clear Output menu item
//------------------------------------------------------------
LONG DoMainMenuClearOut (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_RESETCONTENT, 0, 0);
return 0;
}
//------------------------------------------------------------
// DoMainMenuMinOnRun - Process View/Minimize on Run menu item
//------------------------------------------------------------
LONG DoMainMenuMinOnRun (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
if (bMinOnRun)
bMinOnRun = FALSE;
else
bMinOnRun = TRUE;
return 0;
}
//------------------------------------------------------------
// DoMainMenuFileExit - Process File/Exit menu item
//------------------------------------------------------------
LONG DoMainMenuFileExit (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
DestroyWindow (hWnd); //Destroy window
return 0;
}
//------------------------------------------------------------
// DoMenuAbout - Process File-About command from menu bar.
//------------------------------------------------------------
LONG DoMainMenuAbout (HWND hWnd, UINT idItem, HWND hwndCtl,
UINT wNotifyCode) {
MyDisplayDialog(hInst, "AboutBox", hWnd,
(WNDPROC) AboutDlgProc, 0L);
return 0;
}
//============================================================
// AboutDlgProc - About dialog box dialog procedure
//============================================================
BOOL CALLBACK AboutDlgProc (HWND hWnd, UINT msg, UINT wParam,
LONG lParam) {
if((msg == WM_COMMAND) && (wParam == IDOK)) {
EndDialog(hWnd, 0);
return TRUE;
}
return FALSE;
}
//============================================================
// AskDlgProc - Ask box dialog box dialog procedure
//============================================================
BOOL CALLBACK AskDlgProc (HWND hWnd, UINT msg, UINT wParam,
LONG lParam) {
RECT rectDesk, rectWnd;
INT x, y;
if (msg == WM_INITDIALOG) {
//First, center the box on the screen.
GetWindowRect (GetDesktopWindow(), &rectDesk);
GetWindowRect (hWnd, &rectWnd);
x = (rectDesk.right-rectDesk.left)/2-(rectWnd.right-rectWnd.left)/2;
y = (rectDesk.bottom-rectDesk.top)/2-(rectWnd.bottom-rectWnd.top)/2;
SetWindowPos (hWnd, 0, x, y, 0, 0, SWP_NOSIZE);
//Set the approperate text fields.
SetWindowText (hWnd, szProgName);
SetDlgItemText (hWnd, IDD_ASKTEXT, (char *)LOWORD (lParam));
SetDlgItemText (hWnd, IDD_ASKANS, (char *)HIWORD (lParam));
return 1;
}
if (msg == WM_COMMAND) {
if(wParam == IDOK) {
GetDlgItemText (hWnd, IDD_ASKANS, pszAskAns, MAXLINELEN);
EndDialog(hWnd, 1);
return TRUE;
} else if (wParam == IDCANCEL) {
EndDialog(hWnd, 0);
return TRUE;
}
}
return FALSE;
}
//============================================================
// General Helper Routines
//============================================================
//------------------------------------------------------------
// MyYield - Yields control to other programs, but returns
// if Windows is idle.
//------------------------------------------------------------
BOOL MyYield (void) {
MSG msg;
BOOL bCont;
bCont = TRUE;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
bCont = FALSE;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return bCont;
}
//------------------------------------------------------------
// MyDisplayDialog - Display a dialog box
//------------------------------------------------------------
INT MyDisplayDialog (HINSTANCE hInstance, LPCSTR szDlgName,
HWND hWnd, WNDPROC lpDialogProc,
LPARAM lParam) {
WNDPROC lpDlgProcInst;
INT rc;
lpDlgProcInst = MakeProcInstance(lpDialogProc, hInst);
rc = DialogBoxParam (hInstance, szDlgName, hWnd,
lpDlgProcInst, lParam);
FreeProcInstance(lpDlgProcInst);
return rc;
}
//------------------------------------------------------------
// MyWritePrivateProfileInt - Writes an integer to the profile
//------------------------------------------------------------
BOOL MyWritePrivateProfileInt (char *szSec, char *szEntry,
int Num, int Base, char *szProfile) {
char szStr[33];
itoa (Num, szStr, Base);
return WritePrivateProfileString (szSec, szEntry, szStr,
szProfile);
}
//------------------------------------------------------------
// MyGetFilename - Uses the common File Open dialog box to
// query the user for a filename
//------------------------------------------------------------
BOOL MyGetFilename (HWND hWnd, char *szFilename, INT sMaxLen, char *szFilter,
INT sFilterIndex) {
OPENFILENAME ofn;
*szFilename = '\0';
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.hInstance = hInst;
ofn.lpstrFilter = szFilter;
ofn.lpstrCustomFilter = 0;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = sFilterIndex;
ofn.lpstrFile = szFilename;
ofn.nMaxFile = sMaxLen;
ofn.lpstrFileTitle = 0;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = 0;
ofn.lpstrTitle = 0;
ofn.Flags = OFN_FILEMUSTEXIST;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = "WBT";
ofn.lCustData = 0;
ofn.lpfnHook = 0;
ofn.lpTemplateName = 0;
return (GetOpenFileName (&ofn));
}
//------------------------------------------------------------
// MySubClassWindow - Subclasses a window
//------------------------------------------------------------
WNDPROC MySubClassWindow (HWND hWnd, WNDPROC lpfnNewProc) {
WNDPROC lpfnOldProc;
lpfnOldProc = (WNDPROC) GetWindowLong (hWnd, GWL_WNDPROC);
SetWindowLong (hWnd, GWL_WNDPROC, (LONG) lpfnNewProc);
return lpfnOldProc;
}
//============================================================
// Program specific procedures
//============================================================
//============================================================
// Start of Interpeter code
//============================================================
//------------------------------------------------------------
// InitInterpeter - Initializes the interpeter
//------------------------------------------------------------
INT InitInterpeter (HWND hWnd) {
INT sRC;
FARPROC lpfnLibLoad;
FIND_T fs;
hVarBuff = LocalAlloc (LMEM_MOVEABLE, (UINT) VARBUFFSIZE);
if (hVarBuff == 0) return ERR_OUT_OF_MEMORY;
pbVarBuff = LocalLock (hVarBuff);
hTokBuff = GlobalAlloc (GMEM_MOVEABLE | LMEM_ZEROINIT, TOKBUFFSIZE);
if (hTokBuff == 0) return ERR_OUT_OF_MEMORY;
lpbTokBuff = GlobalLock (hTokBuff);
sRC = _dos_findfirst ("*.WCL", _A_NORMAL, &fs);
while (sRC == 0) {
hLib[sLibCount] = LoadLibrary (fs.name);
if (hLib[sLibCount] < 32) {
sRC = ERR_BAD_LIB_LOAD;
FreeLibrary (hLib[sLibCount]);
break;
}
lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibLoad");
if (lpfnLibLoad == 0) {
sRC = ERR_BAD_LIB_LOAD;
FreeLibrary (hLib[sLibCount]);
break;
}
sRC = ((LPLIBLOAD)*lpfnLibLoad) (hWnd, sLibCount, ERR_LIBERROR_START - sLibCount);
if (sRC) {
sRC = ERR_BAD_LIB_LOAD;
FreeLibrary (hLib[sLibCount]);
break;
}
lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
if (lpfnLibLoad == 0) {
sRC = ERR_BAD_LIB_LOAD;
FreeLibrary (hLib[sLibCount]);
break;
}
lpfnLibFunc[sLibCount] = lpfnLibLoad;
sLibCount++;
sRC = _dos_findnext (&fs);
}
//If loop term due to file not found, RC = 0;
if (sRC == 2) sRC = 0;
// for (i=0; i<MAXLIBS;i++)
// hLib[i]=0;
sRC = ResetInterpeter (hWnd);
if (sRC) return sRC;
if (bAutoStart) {
bRunning = TRUE;
bShowList = FALSE;
bShowOut = TRUE;
}
return sRC;
}
//------------------------------------------------------------
// ResetInterpeter - Resets the interpeter and loads a file.
//------------------------------------------------------------
INT ResetInterpeter (HWND hWnd) {
INT sRC = 0, i, j;
PTOKEN ptArg0;
HCURSOR hcurSave;
FARPROC lpfnLibReset;
pbVarStrings = pbVarBuff;
ptVarList = (PTOKEN) (pbVarStrings + VARBUFFSIZE);
wVarCount = 0;
lpbTokLine = lpbTokBuff;
// Add Operators to token list
for (i = 0; i < dim (OpList); i++) {
sRC = AddTokenInit (OpList[i].szName, OpList[i].ucType,
(WORD) OpList[i].ucLevel,
(DWORD) (LPVOID) OpList[i].Fxn);
if (sRC) break;
}
// Add DOS internal commands to token list
for (i = 0; i < dim (CmdList); i++) {
sRC = AddTokenInit (CmdList[i].szName, TTYPE_INTCMD, 0, 0);
if (sRC) break;
}
// Add Functions to token list
for (i = 0; i < dim (FuncList); i++) {
sRC = AddTokenInit (FuncList[i].szName, FuncList[i].ucType, 0,
(DWORD)(LPVOID) FuncList[i].Fxn);
if (sRC) break;
}
// Add Statements to token list
for (i = 0; i < dim (StatementList); i++) {
sRC = AddTokenInit (StatementList[i].szName,
StatementList[i].ucType, 0,
(DWORD)(LPVOID) StatementList[i].Fxn);
if (sRC) break;
}
// Load Predefined Vars
AddToken ("HINST", TTYPE_NUM, 0, (DWORD) hInst, &sRC);
AddToken ("HMAIN", TTYPE_NUM, 0, (DWORD) hMain, &sRC);
// Load Cmd line arg Tokens
i = 0;
ptArg0 = AddToken ("", TTYPE_STR, 0, (DWORD)(LPSTR) szCmdBuff, &sRC);
if (szCmdBuff[0] != 0) {
for (i = 0; szCmdBuff[i] != 0; i++)
;
i++;
}
j = 1;
while ((szCmdBuff[i] != 0) && (sRC == 0)) {
AddToken ("",TTYPE_STR, 0, (DWORD)(LPSTR)&szCmdBuff[i], &sRC);
for (; szCmdBuff[i] != 0; i++)
;
i++;
j++;
}
if (sRC) return sRC;
AddToken ("",TTYPE_RETVAL, j, (DWORD)(LPVOID)ptArg0, &sRC);
// Add Library Tokens
for (i = 0; i < sLibCount; i++) {
lpfnLibReset = GetProcAddress (hLib[i], "WCLibReset");
if (lpfnLibReset == 0)
sRC = ERR_BAD_LIB_LOAD;
else
sRC = ((LPLIBRESET)*lpfnLibReset) (i, lpfnTokenFuncCallback);
if (sRC) break;
}
if (sRC) {
PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
return 0;
}
// Load file
hcurSave = SetCursor (LoadCursor (NULL, IDC_WAIT));
sRC = LoadProgram (hWnd, &hFileBuff, (LPLINETOKEN) lpbTokLine, (UINT)TOKBUFFSIZE);
SetCursor (hcurSave);
return sRC;
}
//------------------------------------------------------------
// LoadProgram - Loads a program
//------------------------------------------------------------
INT LoadProgram (HWND hWnd, HANDLE *hFileBuff, LPLINETOKEN pltProg, UINT wProgMax) {
INT i, sRC = 0, sErrCnt;
LPLINETOKEN pltLine, pltOld;
char chChar;
LPSTR lpszSource;
LPSTR lpszLineStart;
// Load file
if (szCmdBuff[0] == '\0') {
bHold = TRUE;
return 0;
}
sRC = ReadFile (szCmdBuff, hFileBuff);
if (sRC) {
szCmdBuff[0] = 0;
return sRC;
}
pltLine = pltProg;
lpszSource = (LPSTR) GlobalLock (*hFileBuff);
if (lpszSource == 0)
return ERR_MEM_LOCK;
SendDlgItemMessage (hWnd, IDD_LINELIST, LB_RESETCONTENT, 0, 0L);
i = 0;
sErrCnt = 0;
while (*lpszSource != 0) {
pltOld = pltLine;
lpszLineStart = lpszSource;
sRC = TokenizeLine (&lpszSource, &pltLine, i++);
if (sRC) {
sErrCnt++;
if (sErrCnt > 100) {
sRC = 0;
break;
}
PrintError (hWnd, i, sRC, FALSE);
sRC = 0;
}
chChar = *lpszSource;
*lpszSource = 0;
SendDlgItemMessage (hWnd, IDD_LINELIST, LB_ADDSTRING, 0,
(LPARAM) lpszLineStart);
*lpszSource = chChar;
if ((UINT)(((LPBYTE)pltLine-lpbTokLine) + MAXLINELEN) >= (UINT) TOKBUFFSIZE) {
PrintError (hWnd, i, ERR_FILE_TOO_COMPLEX, FALSE);
sRC = ERR_FILE_TOO_COMPLEX;
break;
}
if (*lpszSource != 0) lpszSource++;
}
pltLine->ucLen = 2;
pltLine->ucType = TTYPE_EOF;
if (strrchr (szCmdBuff, '\\') != 0)
strcpy (szProgName, strrchr (szCmdBuff, '\\')+1);
else if (strlen (szCmdBuff) < sizeof (szProgName) - 1)
strcpy (szProgName, szCmdBuff);
if (strrchr (szProgName, '.') != 0)
*strrchr (szProgName, '.') = 0;
SetWindowText (hMain, szProgName);
bRunning = FALSE;
bAtEnd = FALSE;
wCurrentLine = 0;
PostMessage (hMain, MYMSG_REFRESH, 0, 0);
return sRC;
}
//------------------------------------------------------------
// TermInterpeter - Terminates the interpeter
//------------------------------------------------------------
INT TermInterpeter (void) {
INT i;
for (i = 0; i < sLibCount; i++)
FreeLibrary (hLib[i]);
LocalUnlock (hVarBuff);
LocalFree (hVarBuff);
GlobalUnlock (hTokBuff);
GlobalFree (hTokBuff);
return 0;
}
//------------------------------------------------------------
// ParseCmdLine - Parses the command line
//------------------------------------------------------------
INT ParseCmdLine (LPSTR lpCmdLine) {
INT i, sRC = 0;
// Parse Command line switches
while ((*lpCmdLine == '/') || (*lpCmdLine == '-')) {
lpCmdLine++;
switch (*lpCmdLine) {
case 'l':
case 'L':
bAutoStart = TRUE;
break;
default:
return ERR_UNKNOWN_CMDSWITCH;
}
do {
lpCmdLine++;
} while ((*lpCmdLine != '\0') && (*lpCmdLine <= ' '));
}
if (*lpCmdLine == 0) return 0;
// Copy filename
i = 0;
while ((*lpCmdLine != 0) && (i < sizeof (szCmdBuff))) {
while ((*lpCmdLine != 0) && (*lpCmdLine > ' ') &&
(*lpCmdLine != '/'))
szCmdBuff[i++] = *lpCmdLine++;
szCmdBuff[i++] = 0;
while ((*lpCmdLine != 0) && (*lpCmdLine <= ' '))
*lpCmdLine++;
}
szCmdBuff[i++] = 0;
strupr (szCmdBuff); //Will only cap filename
if (bAutoStart == FALSE)
bAutoStart = TRUE;
else
bAutoStart = FALSE;
return 0;
}
//------------------------------------------------------------
// AddString - Adds a string to the string list
//------------------------------------------------------------
PBYTE AddString (LPSTR lpszString, char *pszPtr, UINT wDLen, INT *sRC) {
UINT wLen, i;
PITEM piItem;
LPSTR lpszPtr;
if (wDLen == 0)
wLen = lstrlen (lpszString);
else
wLen = wDLen;
//If adding a null string, Don't add to string list
if (wLen == 0)
return (PBYTE) szNull;
//See if we have the room
if (pbVarStrings + wLen + 5 >= (PBYTE) ptVarList) {
*sRC = ERR_NO_TOKEN_SPACE;
return 0;
}
piItem = (PITEM) pbVarStrings;
piItem->wLen = wLen + 5;
piItem->wLinkBack = (WORD) pszPtr;
lpszPtr = piItem->szStr;
for (i=0; i < wLen; i++)
*lpszPtr++ = *lpszString++;
*lpszPtr++ = 0;
pbVarStrings = (PBYTE) OFFSETOF (lpszPtr);
return (PBYTE) piItem->szStr;
}
//------------------------------------------------------------
// AppendString - Adds a string to the end of a string
//------------------------------------------------------------
INT AppendString (PTOKEN ptToken, char *szString) {
INT sLen, sLen1;
PITEM piItem;
sLen = strlen ((char *)ptToken->dwData);
sLen1 = strlen (szString);
if (pbVarStrings + sLen + sLen1 + 5 >= (PBYTE) ptVarList)
return ERR_NO_TOKEN_SPACE;
piItem = (PITEM) pbVarStrings;
piItem->wLen = sLen + sLen1 + 5;
piItem->wLinkBack = (WORD) ptToken->dwData;
strcpy (piItem->szStr, (char *)ptToken->dwData);
strcat (piItem->szStr+sLen, szString);
pbVarStrings += sLen + sLen1 + 5;
ptToken->dwData = (DWORD)(LPSTR) piItem->szStr;
return 0;
}
//------------------------------------------------------------
// DeleteString - Deletes a string to the string list
//------------------------------------------------------------
INT DeleteString (char *szString, WORD wLinkBack) {
PITEM piItem, piNext;
PBYTE pbSrc, pbDest;
DWORD *pdwData;
UINT i, wLen;
if (szString == 0) return 0;
if (szString == szNull) return 0;
piItem = (PITEM) (szString-4);
if (piItem->wLinkBack == wLinkBack)
piItem->wLinkBack = 0xffff;
// Compress String list
piNext = piItem;
while ((PBYTE) piNext < pbVarStrings) {
do {
(PBYTE) piNext += piNext->wLen;
} while (((PBYTE) piNext < pbVarStrings) && (piNext->wLinkBack == 0xffff));
if ((PBYTE) piNext >= pbVarStrings)
pbVarStrings = (PBYTE) piItem;
else {
pbSrc = (PBYTE) piNext;
pbDest = (PBYTE) piItem;
wLen = piNext->wLen;
for (i = 0; i < wLen; i++)
*pbDest++ = *pbSrc++;
pdwData = (DWORD *) piItem->wLinkBack;
*pdwData = (DWORD)(LPSTR) &piItem->szStr;
if (pbSrc == pbVarStrings)
pbVarStrings = pbDest;
piItem = (PITEM) pbDest;
piNext = (PITEM) pbSrc;
}
}
return 0;
}
//------------------------------------------------------------
// AddTokenL - Adds a token to the token list
// This routine allows for a FAR pointer to the name.
//------------------------------------------------------------
PTOKEN AddTokenL (LPSTR lpszName, BYTE ucType, UINT wData, DWORD dwData, LPINT sRC) {
char szBuff[MAXSTRLEN+1];
INT sLocRC = 0;
PTOKEN ptRet;
lstrcpy (szBuff, lpszName);
ptRet = AddToken (szBuff, ucType, wData, dwData, &sLocRC);
*sRC = sLocRC;
return ptRet;
}
//------------------------------------------------------------
// AddTokenInit - Special version of Add Token that saves
// space when adding statement and operator tokens.
//------------------------------------------------------------
INT AddTokenInit (char *szName, BYTE ucType, UINT wData, DWORD dwData) {
ptVarList--; //Make room for new token
//See if out of space
if ((PBYTE) ptVarList <= pbVarStrings) {
ptVarList++;
return ERR_NO_TOKEN_SPACE;
return 0;
}
wVarCount++; //Inc token count
ptVarList->pszName = szName;
ptVarList->ucNameLen = (BYTE) strlen (szName);
ptVarList->ucType = ucType;
ptVarList->wData = wData;
ptVarList->dwData = dwData;
return 0;
}
//------------------------------------------------------------
// AddToken - Adds a token to the token list
// If the name ptr = 0, a temporary token is added to the list
//------------------------------------------------------------
PTOKEN AddToken (char *szName, BYTE ucType, UINT wData, DWORD dwData, INT *sRC) {
INT i;
PSTR pszTemp;
//Check to see if name too long
if (szName != 0) {
i = strlen (szName);
if (i > MAXSTRLEN) {
*sRC = ERR_NAME_TOO_LONG;
return 0;
}
} else
i = 0;
ptVarList--; //Make room for new token
//See if out of space
if ((PBYTE) ptVarList <= pbVarStrings) {
ptVarList++;
*sRC = ERR_NO_TOKEN_SPACE;
return 0;
}
wVarCount++; //Inc token count
// Add Name to string list
if (szName != 0) {
pszTemp = AddString ((LPSTR)szName, (char *)&ptVarList->pszName, 0, sRC);
if (*sRC) {
wVarCount--;
ptVarList++;
return 0;
}
} else
pszTemp = szNull;
ptVarList->pszName = pszTemp;
ptVarList->ucNameLen = (BYTE) i;
ptVarList->ucType = ucType;
ptVarList->wData = wData;
ptVarList->dwData = dwData;
if ((ucType == TTYPE_STR) || (ucType == TTYPE_DATA)) {
if (dwData != 0) {
if (ucType == TTYPE_STR)
ptVarList->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData,
(char *)&ptVarList->dwData, 0, sRC);
else
ptVarList->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData,
(char *)&ptVarList->dwData, wData, sRC);
if (*sRC) {
if (ptVarList->ucNameLen)
DeleteString (ptVarList->pszName, (WORD)&ptVarList->pszName);
wVarCount--;
ptVarList++;
return 0;
}
}
}
return ptVarList;
}
//------------------------------------------------------------
// FindToken - Finds a token in the token list
//------------------------------------------------------------
PTOKEN FindToken (LPSTR lpszTokenName, INT sNameLen) {
UINT i;
char chChar;
PTOKEN ptList;
BOOL bFound = FALSE;
if (sNameLen > 255) return 0;
ptList = ptVarList;
if (sNameLen == 0) {
for (i = 0; i < wVarCount; i++) {
if ((WORD)ptList->pszName == (WORD)OFFSETOF (lpszTokenName)) {
bFound = TRUE;
break;
}
}
ptList++;
} else {
chChar = *(lpszTokenName+sNameLen);
*(lpszTokenName+sNameLen) = 0;
for (i = 0; i < wVarCount; i++) {
if ((INT) ptList->ucNameLen == sNameLen) {
if (lstrcmp (ptList->pszName, lpszTokenName) == 0) {
bFound = TRUE;
break;
}
}
ptList++;
}
*(lpszTokenName+sNameLen) = chChar;
}
if (bFound)
return ptList;
else
return 0;
}
//------------------------------------------------------------
// FindTokenByType - Finds the most recient token of a given type
//------------------------------------------------------------
PTOKEN FindTokenByType (BYTE ucType) {
PTOKEN ptList;
BOOL bFound = FALSE;
UINT i;
ptList = ptVarList;
for (i = 0; i < wVarCount; i++) {
if (ptList->ucType == ucType) {
bFound = TRUE;
break;
}
ptList++;
}
if (bFound)
return ptList;
else
return 0;
}
//------------------------------------------------------------
// TokFuncCallback - External entry point
//------------------------------------------------------------
DWORD CALLBACK TokFuncCallback (INT sFunction, LPTOKEN lptDest,
LPSTR lpszName, BYTE ucNewType, UINT wData, DWORD dwData) {
INT sRC = 0;
PTOKEN ptDest;
ptDest = (PTOKEN)LOWORD(lptDest);
switch (sFunction) {
case CBF_ADDTOKEN:
AddTokenL (lpszName, ucNewType, wData, dwData, &sRC);
return (DWORD) sRC;
case CBF_FINDTOKEN:
return (DWORD) (LPTOKEN) FindToken (lpszName, wData);
case CBF_SETTOKEN:
return (DWORD) SetToken (ptDest, ucNewType, wData, dwData);
case CBF_GETTOKENVAL:
return GetTokenVal (ptDest);
case CBF_GETTOKENSTRING:
return (DWORD) GetTokenStringL (ptDest);
case CBF_RESOLVELINE:
return (DWORD) ResolveLine ((LPLINETOKEN *)dwData, lpszName, wData);
default:
return ERR_BAD_FUNC;
}
}
//------------------------------------------------------------
// SetToken - Sets a token to a new value
//------------------------------------------------------------
INT SetToken (PTOKEN ptDest, BYTE ucNewType, UINT wData, DWORD dwData) {
INT sRC = 0;
if ((ptDest->ucType != TTYPE_NUM) && (ptDest->ucType != TTYPE_STR) &&
(ptDest->ucType != TTYPE_DATA))
return ERR_ILLEGAL_ASSIGNMENT;
if ((ptDest->ucType != TTYPE_NUM) &&
((char *)ptDest->dwData != ptDest->pszName))
DeleteString ((char *)ptDest->dwData, (WORD) &ptDest->dwData);
ptDest->ucType = ucNewType;
ptDest->wData = wData;
ptDest->dwData = dwData;
if ((ucNewType == TTYPE_STR) || (ucNewType == TTYPE_DATA)) {
if (ucNewType == TTYPE_STR)
ptDest->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData,
(char *)&ptDest->dwData, 0, &sRC);
else
ptDest->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData,
(char *)&ptDest->dwData, wData, &sRC);
}
if (sRC)
ptDest->dwData = (DWORD)(LPSTR) ptDest->pszName;
return sRC;
}
//------------------------------------------------------------
// DeleteToken - Deltes a token in the token list
//------------------------------------------------------------
INT DeleteToken (PTOKEN ptToken) {
if (ptToken->ucNameLen != 0)
DeleteString (ptToken->pszName, (WORD)&ptToken->pszName);
if (((ptToken->ucType == TTYPE_STR) || (ptToken->ucType == TTYPE_DATA)) &&
((char *)ptToken->dwData != ptToken->pszName))
DeleteString ((char *)ptToken->dwData, (WORD)&ptToken->dwData);
if (ptToken == ptVarList) {
ptVarList++;
wVarCount--;
} else
ptToken->ucType = TTYPE_DEL;
return 0;
}
//------------------------------------------------------------
// GetTokenStringL - Returns a pointer to the string value
// for a token.
//------------------------------------------------------------
LPSTR GetTokenStringL (PTOKEN ptDest) {
switch (ptDest->ucType) {
case TTYPE_NUM:
ltoa (ptDest->dwData, szTemp, 10);
return (LPSTR) szTemp;
case TTYPE_DATA:
case TTYPE_STR:
if (ptDest->dwData != 0)
return (LPSTR) ptDest->dwData;
//If no string, fall through to default code
default:
if (ptDest->ucNameLen == 0) {
szTemp[0] = 0;
return (LPSTR)szTemp;
} else
return (LPSTR) ptDest->pszName;
}
}
//------------------------------------------------------------
// GetTokenString - Returns a pointer to the string value
// for a token.
//------------------------------------------------------------
char *GetTokenString (PTOKEN ptDest) {
switch (ptDest->ucType) {
case TTYPE_NUM:
ltoa (ptDest->dwData, szTemp, 10);
return szTemp;
case TTYPE_DATA:
case TTYPE_STR:
if (ptDest->dwData != 0)
return (char *) ptDest->dwData;
//If no string, fall through to default code
default:
if (ptDest->ucNameLen == 0) {
szTemp[0] = 0;
return szTemp;
} else
return ptDest->pszName;
}
}
//------------------------------------------------------------
// GetTokenVal - Returns a pointer to the numberic value
// for a token.
//------------------------------------------------------------
LONG GetTokenVal (PTOKEN ptDest) {
if (ptDest->ucType == TTYPE_NUM)
return ptDest->dwData;
else
return atol ((char *)GetTokenString (ptDest));
}
//------------------------------------------------------------
// FindChar - finds the next non-space character
//------------------------------------------------------------
LPSTR FindChar (LPSTR lpszLine) {
while (*lpszLine != '\0') {
if (*lpszLine == '\n') {
break;
}
if (*lpszLine == 0x0d) {
*lpszLine = ' ';
}
if (*lpszLine > ' ') break;
lpszLine++;
}
return lpszLine;
}
//------------------------------------------------------------
// UCaseLine - Converts line to uppercase.
//------------------------------------------------------------
void UCaseLine (LPSTR lpszLine) {
BOOL bInQuote = FALSE;
while (*lpszLine != '\0' && *lpszLine != '\n') {
if (!bInQuote) {
if (*lpszLine >= 'a' && *lpszLine <= 'z')
*lpszLine = *lpszLine & (char) 0xdf;
}
if (*lpszLine == '"')
bInQuote = !bInQuote;
lpszLine++;
}
return;
}
//------------------------------------------------------------
// ComputeNum - Converts token to number
//------------------------------------------------------------
LONG ComputeNum (LPSTR *lpszLine, INT *sRC) {
LONG lNum = 0, lTemp, lOld;
INT sBase = 10;
BYTE ucChar;
if (**lpszLine == '0')
switch (*(*lpszLine+1)) {
case 'X':
sBase = 16;
(*lpszLine) += 2;
break;
case 'O':
sBase = 8;
(*lpszLine) += 2;
break;
case 'B':
sBase = 2;
(*lpszLine) += 2;
break;
default:
sBase = 10;
}
ucChar = **lpszLine;
while ((ucChar >= '0' && ucChar <= '9') ||
((ucChar >= 'A' && ucChar <= 'F') && sBase == 16)) {
if (ucChar <= '9')
lTemp = (LONG) ucChar - '0';
else
lTemp = (LONG) (ucChar - 'A' + 10);
if (lTemp >= sBase)
break;
lOld = lNum;
lNum = (lNum * sBase) + lTemp;
(*lpszLine)++;
ucChar = **lpszLine;
if (sBase == 10) {
if (lOld > lNum) {
*sRC = ERR_OVERFLOW;
break;
}
} else {
if ((DWORD) lOld > (DWORD) lNum) {
*sRC = ERR_OVERFLOW;
break;
}
}
}
return lNum;
}
//------------------------------------------------------------
// TokenizeLine - Tokenizes the line.
//------------------------------------------------------------
INT TokenizeLine (LPSTR *plpszLineIn, LPLINETOKEN *ppbTokOut, UINT wLineNum) {
LPSTR lpszLine;
LPSTR lpszTokStart;
LONG lNum;
char chChar;
BYTE ucNameLen;
INT sRC = 0;
LPLINETOKEN pltOut;
LPLINESTARTTOK plstStart;
PTOKEN ptOldTok;
lpszLine = *plpszLineIn;
pltOut = *ppbTokOut;
plstStart = (LPLINESTARTTOK) pltOut;
plstStart->ucLen = 6;
plstStart->ucType = TTYPE_LINE;
plstStart->wLineNum = wLineNum;
(PBYTE) pltOut += 6;
UCaseLine (lpszLine);
lpszLine = FindChar (lpszLine);
while ((*lpszLine != '\n') && (*lpszLine != '\0') && (sRC == 0)) {
lpszTokStart = lpszLine;
ucNameLen = 0;
//Check for number
if ((*lpszTokStart >= '0') && (*lpszTokStart <= '9')) {
lNum = ComputeNum (&lpszLine, &sRC);
if (sRC) break;
if ((lNum > 32767) || (lNum < -32767)) {
pltOut->ucType = TTYPE_LCONST;
pltOut->ucLen = 6;
((LPVARLCONST) pltOut)->lData = lNum;
(PBYTE) pltOut += 6;
} else {
pltOut->ucType = TTYPE_SCONST;
pltOut->ucLen = 4;
((LPVARSCONST) pltOut)->sData = (INT) lNum;
(PBYTE) pltOut += 4;
}
//check for quoted string
} else if (*lpszTokStart == '"') {
lpszLine++;
lpszTokStart++;
do {
ucNameLen++;
lpszLine++;
} while ((*lpszLine != '\n') && (*lpszLine != '\0') &&
(*lpszLine != '"') && (ucNameLen < MAXSTRLEN));
if (*lpszLine == '"') {
pltOut->ucType = TTYPE_STRCONST;
pltOut->ucLen = (BYTE) (ucNameLen + 3);
chChar = *lpszLine;
*lpszLine = '\0';
lstrcpy ((LPSTR) &pltOut->ptToken, lpszTokStart);
*lpszLine = chChar;
(PBYTE) pltOut += ucNameLen + 3;
lpszLine++;
} else
sRC = ERR_NO_END_QUOTE;
//Otherwise it can be tokenized
} else {
//See if allowable variable
if (((*lpszTokStart >= 'A') && (*lpszTokStart <= 'Z')) ||
(*lpszTokStart == '_') ) {
do {
ucNameLen++;
lpszLine++;
} while ((ucNameLen < MAXSTRLEN ) &&
(((*lpszLine >= 'A') && (*lpszLine <= 'Z')) ||
((*lpszLine >= '0') && (*lpszLine <= '9')) ||
(*lpszLine == '_') || (*lpszLine == '.') ||
(*lpszLine == '$') ));
//Must be operator, or other string constant
} else {
do {
ucNameLen++;
lpszLine++;
} while ((ucNameLen < 2) &&
(*lpszLine != '_') &&
(((*lpszLine > ' ') && (*lpszLine < '0')) ||
((*lpszLine > '9') && (*lpszLine < 'A')) ||
(*lpszLine > 'Z') ));
ptOldTok = FindToken (lpszTokStart, 2);
if ((ptOldTok == 0) && (ucNameLen == 2)) {
ucNameLen = 1;
lpszLine--;
}
}
ptOldTok = FindToken (lpszTokStart, ucNameLen);
if (ptOldTok == 0) {
chChar = *lpszLine;
*lpszLine = 0;
if (*lpszLine == ':')
ptOldTok = AddTokenL (lpszTokStart, TTYPE_LABEL, 0,
(DWORD)(LPVOID)pltOut, &sRC);
else
ptOldTok = AddTokenL (lpszTokStart, TTYPE_STR, 0, 0, &sRC);
*lpszLine = chChar;
pltOut->ucType = TTYPE_VAR;
} else {
// If comment, skip to end of line
if (ptOldTok->ucType == TTYPE_CMT2EOL) {
while ((*lpszLine != '\n') && (*lpszLine != '\0')) {
if (*lpszLine == 0x0d)
*lpszLine = ' ';
lpszLine++;
}
break;
}
switch (ptOldTok->ucType) {
case TTYPE_NUM:
case TTYPE_STR:
if (*lpszLine == ':') {
ptOldTok->ucType = TTYPE_LABEL;
ptOldTok->dwData = (DWORD)(LPVOID)pltOut;
} else
pltOut->ucType = TTYPE_VAR;
break;
case TTYPE_LABEL:
if (*lpszLine == ':')
sRC = ERR_MULTI_DEF_LABEL;
break;
default:
pltOut->ucType = ptOldTok->ucType;
}
}
if (*lpszLine == ':')
lpszLine++;
else {
pltOut->ucLen = 4;
pltOut->ptToken = ptOldTok;
(PBYTE) pltOut += 4;
}
}
lpszLine = FindChar (lpszLine);
}
if ((*lpszLine != '\n') || (*lpszLine != '\0'))
while ((*lpszLine != '\n') && (*lpszLine != '\0'))
lpszLine++;
pltOut->ucLen = 2;
pltOut->ucType = TTYPE_EOL;
(PBYTE) pltOut += 2;
plstStart->wLineLen = (LPBYTE) pltOut - (LPBYTE) plstStart;
*plpszLineIn = lpszLine;
*ppbTokOut = pltOut;
return sRC;
}
//------------------------------------------------------------
// ResolveLine - Converts line tokens to text
//------------------------------------------------------------
INT ResolveLine (LPLINETOKEN *pltCurrToken, LPSTR lpszOutput, INT sMaxSize) {
PTOKEN ptTemp;
INT sRC = 0;
*lpszOutput = '\0';
while ((*pltCurrToken)->ucType != TTYPE_EOL) {
ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC) break;
sRC = Eval (pltCurrToken, ptTemp, FUNC_EXECUTE);
if (sRC) {
DeleteToken (ptTemp);
break;
}
lstrcat (lpszOutput, GetTokenStringL (ptTemp));
DeleteToken (ptTemp);
lstrcat (lpszOutput, " ");
}
return sRC;
}
//------------------------------------------------------------
// SkipLine - Scan until start of next line
//------------------------------------------------------------
LONG SkipLine (LPLINETOKEN *pltStart) {
while ((*pltStart)->ucType != TTYPE_EOL)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
return 0;
}
//------------------------------------------------------------
// WriteOutput - Writes a line to the output listbox
//------------------------------------------------------------
void WriteOutput (HWND hWnd, char *pszOutput) {
LONG index;
SendDlgItemMessage (hWnd, IDD_OUTLIST, WM_SETREDRAW, FALSE, 0);
if (SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_GETCOUNT, 0, 0) > MAXOUTLINES)
SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_DELETESTRING, 0, 0);
index = SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_ADDSTRING, 0,
(LPARAM)(LPSTR) pszOutput);
SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_SETTOPINDEX, (WORD)index, 0);
SendDlgItemMessage (hWnd, IDD_OUTLIST, WM_SETREDRAW, TRUE, 0);
if (IsIconic (hWnd)) {
bShowOut = TRUE;
ShowWindow (hWnd, SW_RESTORE);
} else if (!bShowOut) {
bShowOut = TRUE;
PostMessage (hWnd, MYMSG_REFRESH, 0, 0);
}
bAutoStart = FALSE;
return;
}
//------------------------------------------------------------
// PrintError - Displays an error message on the output listbox
//------------------------------------------------------------
void PrintError (HWND hWnd, INT sLineNum, INT sErrorCode, BOOL bSetList) {
char szTempStr[MAXLINELEN];
char szErrorStr[50];
strcpy (szTempStr, "Error - Line: ");
itoa (sLineNum+1, szTemp, 10);
strcat (szTempStr, szTemp);
strcat (szTempStr, " ");
if (sErrorCode > 0)
sErrorCode += 11;
else
sErrorCode = abs (sErrorCode);
if (LoadString (hInst, sErrorCode, szErrorStr, sizeof (szErrorStr)) == 0) {
itoa (sErrorCode, szErrorStr, 10);
strcat (szTempStr, "Error number: ");
}
strcat (szTempStr, szErrorStr);
WriteOutput (hWnd, szTempStr);
if (bSetList) {
bShowList = TRUE;
bShowOut = TRUE;
PostMessage (hWnd, MYMSG_REFRESH, 0, 0);
SetActiveWindow (hWnd);
}
return;
}
//----------------------------------------------------------------------
// Read File - Allocates a buff in global memory and reads in a file
//----------------------------------------------------------------------
INT ReadFile (char *szFileName, HANDLE *hFileBuff) {
OFSTRUCT ofFile;
HFILE hFileHandle;
UINT wBytesRead;
LPBYTE lpbFileBuff;
if (*hFileBuff != 0)
GlobalFree (*hFileBuff);
*hFileBuff = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, 65535);
if (*hFileBuff == 0) return ERR_OUT_OF_MEMORY;
lpbFileBuff = GlobalLock (*hFileBuff);
hFileHandle = OpenFile (szFileName, &ofFile, OF_READ);
if (hFileHandle == -1) {
GlobalUnlock (*hFileBuff);
GlobalFree (*hFileBuff);
return ERR_FOPEN_ERR - ofFile.nErrCode;
}
wBytesRead = _lread (hFileHandle, lpbFileBuff, (WORD)65534);
_lclose (hFileHandle);
if (wBytesRead == 65534) {
GlobalUnlock (*hFileBuff);
GlobalFree (*hFileBuff);
return ERR_FILE_TOO_BIG;
}
*(lpbFileBuff + wBytesRead) = 0;
GlobalUnlock (*hFileBuff);
GlobalReAlloc (*hFileBuff, wBytesRead+1, 0);
return 0;
}
//------------------------------------------------------------
// StuffVKey - Stuffs a virtual key into the system message
// queue.
//------------------------------------------------------------
void WINAPI Keybd_Event (void);
void StuffVKey (BYTE ucVKey, BOOL bMake) {
WORD RegAX, RegBX;
if (bMake)
RegAX = (WORD) ucVKey;
else
RegAX = 0x8000 | (WORD) ucVKey;
RegBX = (WORD) MapVirtualKey (ucVKey, 0);
_asm {
mov ax,RegAX
mov bx,RegBX
}
Keybd_Event();
}
//------------------------------------------------------------
// StuffOneKey - Processes a character in a stuff key string
//------------------------------------------------------------
INT StuffOneKey (char **pszString) {
BYTE ucVKey, ucShift = 0;
INT sRC = 0, sRepCnt = 0, i;
UINT wKey;
BOOL bFound;
char *pszEnd;
char *pszNum;
bFound = FALSE;
ucVKey = **pszString;
if (ucVKey == 0) return 0;
(*pszString)++;
switch (ucVKey) {
case '+':
ucShift = VK_SHIFT;
break;
case '%':
ucShift = VK_MENU;
break;
case '^':
ucShift = VK_CONTROL;
break;
case '(':
sRC = StuffKeyString (pszString);
if (sRC == 1)
return 0;
else if (sRC == 0)
return ERR_BAD_SENDKEY_STR;
else
return sRC;
case ')':
return 1;
case '{':
if (*(*pszString+1) == '}') {
ucVKey = **pszString;
(*pszString) += 2;
} else {
pszEnd = strchr (*pszString, '}');
if (pszEnd == 0) return ERR_BAD_SENDKEY_STR;
*pszEnd = 0;
pszNum = strchr (*pszString, ' ');
if (pszNum != 0) *pszNum = 0;
for(i = 0; i < dim(SKList); i++) {
if (strcmpi (SKList[i].szName, *pszString) == 0) {
bFound = TRUE;
break;
}
}
if (!bFound) return ERR_BAD_SENDKEY_STR;
ucVKey = SKList[i].ucKey;
if (pszNum != 0) {
*pszNum++ = ' ';
(*pszString) = pszNum;
sRepCnt = atoi(pszNum);
}
*pszEnd++ = '}';
(*pszString) = pszEnd;
}
break;
}
if (ucShift) {
StuffVKey (ucShift, TRUE);
StuffOneKey (pszString);
StuffVKey (ucShift, FALSE);
} else {
if (!bFound) {
wKey = VkKeyScan (ucVKey);
ucVKey = (BYTE) wKey;
} else wKey = 0;
if (HIBYTE (wKey) == 1) {
StuffVKey (VK_SHIFT, TRUE);
StuffVKey (ucVKey, TRUE);
StuffVKey (ucVKey, FALSE);
StuffVKey (VK_SHIFT, FALSE);
} else {
StuffVKey (ucVKey, TRUE);
StuffVKey (ucVKey, FALSE);
}
}
return sRC;
}
//------------------------------------------------------------
// StuffKeyString - Stuffs a 'stuff key' string into the
// system event queue.
//------------------------------------------------------------
INT StuffKeyString (char **pszString) {
INT sRC = 0;
while ((**pszString != 0) && (sRC == 0))
sRC = StuffOneKey (pszString);
return sRC;
}
//------------------------------------------------------------
// CallFunc - Calls user defined and built in functions
//------------------------------------------------------------
INT CallFunc (LPLINETOKEN *pltLine, PTOKEN ptCurrValue, INT sFunc) {
LPLINETOKEN pltFunc;
PTOKEN ptInd;
PTOKEN ptNextValue, ptArg1;
INT sRC = 0, sTokCnt;
UINT wTemp;
ptInd = (*pltLine)->ptToken;
sTokCnt = (*pltLine)->ucLen;
*(PWORD)pltLine += sTokCnt;
// If no open paren, just return func name as string
if ((*pltLine)->ucType != TTYPE_OPAREN) {
ptCurrValue->ucType = TTYPE_STR;
ptCurrValue->wData = 0;
ptCurrValue->dwData = (DWORD)(LPSTR)ptInd->pszName;
return 0;
}
sTokCnt = (*pltLine)->ucLen;
*(PWORD)pltLine += sTokCnt;
// Push arguments onto var list
ptArg1 = AddToken (0, TTYPE_STR, 0, (DWORD)(LPSTR)ptInd->pszName, &sRC);
if (sRC) return sRC;
sTokCnt = 1;
while (((*pltLine)->ucType != TTYPE_CPAREN) &&
((*pltLine)->ucType != TTYPE_EOL) && (sRC == 0)) {
ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
sRC = Eval (pltLine, ptNextValue, sFunc);
sTokCnt++;
}
if ((sRC == 0) && (sFunc == FUNC_EXECUTE)) {
switch (ptInd->ucType) {
case TTYPE_LABEL:
SetToken (ptCurrValue, TTYPE_RETVAL, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
ptCurrValue->ucType = TTYPE_RETVAL;
pltFunc = (LPLINETOKEN) ptInd->dwData;
wTemp = wCurrentLine;
while (sRC == 0)
sRC = ExecuteLine (&pltFunc, FUNC_EXECUTE);
if (sRC == RC_END_OF_SUB) {
sRC = 0;
wCurrentLine = wTemp;
}
break;
case TTYPE_LOCALFUNC:
SetToken (ptCurrValue, TTYPE_NUM, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
sRC = (*((PFUNCTOK)ptInd)->Fxn)(pltLine, ptCurrValue);
break;
case TTYPE_LIBFUNC:
SetToken (ptCurrValue, TTYPE_NUM, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
sRC = ((LPLIBFUNC)*(lpfnLibFunc[HIWORD(ptInd->dwData)]))
(pltLine, (LPTOKEN)ptCurrValue, LOWORD (ptInd->dwData),
lpfnTokenFuncCallback, hMain);
break;
default:
sRC = ERR_FUNC_NOT_FOUND;
break;
}
}
// Remove arg tokens from var list
while (--sTokCnt >= 0)
DeleteToken (ptArg1-sTokCnt);
if (sRC) return sRC;
if ((*pltLine)->ucType != TTYPE_CPAREN)
return ERR_NO_CLOSE_PAREN;
sTokCnt = (*pltLine)->ucLen;
*(PWORD)pltLine += sTokCnt;
return sRC;
}
//------------------------------------------------------------
// GetOp - Recursive routine that evaluates an expression
//------------------------------------------------------------
INT GetOp (LPLINETOKEN *pltLine, PTOKEN ptCurrValue, UINT *wLevel, INT sFunc) {
UINT oldLevel, wNewLev;
INT sRC = 0;
BYTE ucTokLen;
POPTOK potTokIndirect;
PTOKEN ptInd;
PTOKEN ptNextValue;
ucTokLen = (*pltLine)->ucLen;
switch ((*pltLine)->ucType) {
case TTYPE_SCONST:
sRC = SetToken (ptCurrValue, TTYPE_NUM, 0,
(DWORD)((LPVARSCONST) *pltLine)->sData);
*(PWORD)pltLine += ucTokLen;
break;
case TTYPE_LCONST:
sRC = SetToken (ptCurrValue, TTYPE_NUM, 0,
(DWORD)((LPVARLCONST) *pltLine)->lData);
*(PWORD)pltLine += ucTokLen;
break;
case TTYPE_STRCONST:
sRC = SetToken (ptCurrValue, TTYPE_STR, 0,
(DWORD)(LPSTR)((LPSTRCONST)*pltLine)->szData);
*(PWORD)pltLine += ucTokLen;
break;
case TTYPE_VAR:
ptInd = (PTOKEN) (*pltLine)->ptToken;
switch (ptInd->ucType) {
case TTYPE_LABEL:
sRC = CallFunc (pltLine, ptCurrValue, sFunc);
break;
case TTYPE_NUM:
sRC = SetToken (ptCurrValue, ptInd->ucType, ptInd->wData,
GetTokenVal(ptInd));
*(PWORD)pltLine += ucTokLen;
break;
case TTYPE_DATA:
case TTYPE_STR:
sRC = SetToken (ptCurrValue, ptInd->ucType, ptInd->wData,
(DWORD)GetTokenStringL(ptInd));
*(PWORD)pltLine += ucTokLen;
break;
default:
sRC = ERR_SYNTAX;
break;
}
break;
case TTYPE_OPAREN:
ptInd = (*pltLine)->ptToken;
*(PWORD)pltLine += ucTokLen;
if (sFunc == FUNC_EXECUTE) {
sRC = (*((PFUNCTOK)ptInd)->Fxn)(pltLine, ptCurrValue);
} else {
Eval2Num (pltLine, sFunc, &sRC);
if (sRC) return sRC;
if ((*pltLine)->ucType != TTYPE_CPAREN)
return ERR_NO_CLOSE_PAREN;
else
*(PWORD)pltLine += (*pltLine)->ucLen;
}
break;
case TTYPE_LIBFUNC:
case TTYPE_LOCALFUNC:
sRC = CallFunc (pltLine, ptCurrValue, sFunc);
break;
case TTYPE_LUOP:
potTokIndirect = (POPTOK) (*pltLine)->ptToken;
*(PWORD)pltLine += ucTokLen;
//Kluge to allow minus sign to have 2 levels, 13 for
//reguar op and 15 for unary op.
if (potTokIndirect->wLevel == 13)
wNewLev = 15;
else
wNewLev = potTokIndirect->wLevel;
if (*wLevel >= wNewLev) {
*wLevel = wNewLev;
return 0;
} else {
oldLevel = *wLevel;
*wLevel = wNewLev;
ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC) return sRC;
sRC = GetOp (pltLine, ptNextValue, wLevel, sFunc);
if (sRC) return sRC;
sRC = (*potTokIndirect->Fxn)(pltLine, ptCurrValue, ptNextValue);
DeleteToken (ptNextValue);
*wLevel = oldLevel;
}
break;
default:
if ((*pltLine)->ucType < TTYPE_EOL) {
ptInd = (PTOKEN) (*pltLine)->ptToken;
if (ptInd->ucNameLen != 0) {
SetToken (ptCurrValue, TTYPE_STR, 0, (DWORD)GetTokenStringL(ptInd));
*(PWORD)pltLine += ucTokLen;
break;
}
sRC = ERR_EXPECTED_NUMBER;
}
sRC = ERR_EXPECTED_NUMBER;
}
if (sRC) return sRC;
oldLevel = (*wLevel)++;
while (oldLevel < *wLevel) {
*wLevel = oldLevel;
ucTokLen = (*pltLine)->ucLen;
if ((*pltLine)->ucType == TTYPE_EOL) {
*wLevel = 0;
return 0;
} else {
if (((*pltLine)->ucType == TTYPE_LOP) ||
((*pltLine)->ucType == TTYPE_LUOP) ||
((*pltLine)->ucType == TTYPE_ASSIGN_CMP)) {
potTokIndirect = (POPTOK)(*pltLine)->ptToken;
if (*wLevel >= potTokIndirect->wLevel) {
*wLevel = potTokIndirect->wLevel;
return 0;
} else {
*wLevel = potTokIndirect->wLevel;
*(PWORD)pltLine += ucTokLen;
ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC) return sRC;
sRC = GetOp (pltLine, ptNextValue, wLevel, sFunc);
if (sRC) return sRC;
sRC = (*potTokIndirect->Fxn)(pltLine, ptCurrValue, ptNextValue);
DeleteToken (ptNextValue);
}
} else if ((*pltLine)->ucType == TTYPE_OPAREN) {
sRC = ERR_BAD_FUNC_NAME;
break;
} else if ((*pltLine)->ucType == TTYPE_BREAK) {
*(PWORD)pltLine += (*pltLine)->ucLen;
*wLevel = 0;
} else {
*wLevel = 0;
}
}
}
return sRC;
}
//------------------------------------------------------------
// Eval - Returns a token for an expression
//------------------------------------------------------------
INT Eval (LPLINETOKEN *pltLine, PTOKEN ptOut, INT sFunc) {
UINT wLevel = 1;
return GetOp (pltLine, ptOut, &wLevel, sFunc);
}
//------------------------------------------------------------
// Eval2Num - Returns a number value for an expression
//------------------------------------------------------------
LONG Eval2Num (LPLINETOKEN *pltLine, INT sFunc, INT *sRC) {
UINT wLevel = 1;
LONG lResult;
PTOKEN ptTemp;
ptTemp = AddToken (0, TTYPE_NUM, 0, 0, sRC);
if (*sRC) return 0;
*sRC = GetOp (pltLine, ptTemp, &wLevel, sFunc);
lResult = GetTokenVal (ptTemp);
DeleteToken (ptTemp);
return lResult;
}
//------------------------------------------------------------
// GetStatementType - Returns type of next token
//------------------------------------------------------------
BYTE GetStatementType (LPLINETOKEN pltNext) {
if (pltNext->ucType == TTYPE_LINE)
(PBYTE)pltNext += pltNext->ucLen;
if (pltNext->ucType == TTYPE_CMT2EOL) {
while (pltNext->ucType != TTYPE_EOL)
(PBYTE)pltNext += pltNext->ucLen;
(PBYTE)pltNext += pltNext->ucLen;
return GetStatementType (pltNext);
}
return pltNext->ucType;
}
//------------------------------------------------------------
// ExecuteLine - Evaluates and calls the proper routine to
// execute a line in the file.
//------------------------------------------------------------
INT ExecuteLine (LPLINETOKEN *pltCurrent, INT sFunc) {
BOOL bContinue;
INT sRC = 0;
if ((*pltCurrent)->ucType == TTYPE_EOF) {
bRunning = FALSE;
return RC_END_OF_PROGRAM;
}
if (sFunc & FUNC_EXECUTE) {
if (!bRunning) {
bHold = TRUE;
if ((*pltCurrent)->ucType == TTYPE_LINE) {
wCurrentLine = ((LPLINESTARTTOK) *pltCurrent)->wLineNum;
}
PostMessage (hMain, MYMSG_REFRESH, 0, 0);
}
//Use Until loop to insure at least 1 yield per statement
do {
bContinue = MyYield();
} while (bHold && bContinue);
//If we recieved a WM_QUIT, report it
if (!bContinue)
return ERR_UNEXP_PROGTERM;
}
//Execute a line
sRC = Execute (pltCurrent, sFunc);
return sRC;
}
//------------------------------------------------------------
// Execute - Processes a series of tokens.
//------------------------------------------------------------
INT Execute (LPLINETOKEN *pltStart, INT sFunc) {
LPLINETOKEN pltCurr, pltNext;
PSTATEMENTTOK pstTokIndirect;
INT sRC = 0;
PTOKEN ptTemp;
pltCurr = *pltStart;
if (pltCurr->ucType == TTYPE_LINE) {
wCurrentLine = ((LPLINESTARTTOK) pltCurr)->wLineNum;
(PBYTE) pltCurr += pltCurr->ucLen;
}
(LPBYTE) pltNext = (LPBYTE) pltCurr + pltCurr->ucLen;
switch (pltCurr->ucType) {
case TTYPE_INTCMD:
case TTYPE_STRCONST:
sRC = LocalLaunch (&pltCurr, sFunc);
*pltStart = pltCurr;
break;
case TTYPE_VAR:
if (sFunc == FUNC_EXECUTE) {
if ((pltNext->ucType == TTYPE_ASSIGN) ||
(pltNext->ucType == TTYPE_ASSIGN_CMP))
sRC = LocalAssign (&pltCurr, sFunc);
else {
ptTemp = pltCurr->ptToken;
if (ptTemp->ucType == TTYPE_LABEL) {
ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC == 0) {
sRC = Eval (&pltCurr, ptTemp, sFunc);
DeleteToken (ptTemp);
}
} else
sRC = LocalLaunch (&pltCurr, sFunc);
}
} else
SkipLine (&pltCurr);
*pltStart = pltCurr;
break;
case TTYPE_ENDBLK:
case TTYPE_THENELSE:
case TTYPE_LSTATEMENT:
pstTokIndirect = (PSTATEMENTTOK)pltCurr->ptToken;
sRC = (*pstTokIndirect->Fxn)(pltStart, sFunc);
break;
case TTYPE_LIBFUNC:
case TTYPE_LOCALFUNC:
if (sFunc == FUNC_EXECUTE) {
ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC == 0) {
sRC = Eval (&pltCurr, ptTemp, sFunc);
DeleteToken (ptTemp);
if (pltCurr->ucType == TTYPE_EOL)
(PBYTE)pltCurr += (WORD) pltCurr->ucLen;
}
} else
SkipLine (&pltCurr);
*pltStart = pltCurr;
break;
case TTYPE_EOL:
(PBYTE)pltCurr += (WORD) pltCurr->ucLen;
*pltStart = pltCurr;
break;
case TTYPE_EOF:
*pltStart = pltCurr;
bRunning = FALSE;
bHold = TRUE;
sRC = RC_END_OF_PROGRAM;
break;
default:
return ERR_SYNTAX;
}
return sRC;
}
//------------------------------------------------------------
// LocalAssign - Assign a value to a token
//------------------------------------------------------------
INT LocalAssign (LPLINETOKEN *pltStart, INT sFunc){
LPLINETOKEN pltNext;
INT sRC = 0;
PTOKEN ptTemp, ptToken;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
pltNext = *pltStart;
ptToken = (*pltStart)->ptToken;
(PBYTE) pltNext += pltNext->ucLen;
(PBYTE) pltNext += pltNext->ucLen;
ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
if (sRC == 0) {
sRC = Eval (&pltNext, ptTemp, sFunc);
if ((sRC == 0) && (sFunc & FUNC_EXECUTE)) {
ptToken = (*pltStart)->ptToken;
if (ptTemp->ucType == TTYPE_NUM)
sRC = SetToken (ptToken, ptTemp->ucType, ptTemp->wData,
GetTokenVal (ptTemp));
else
sRC = SetToken (ptToken, ptTemp->ucType, ptTemp->wData,
(DWORD)GetTokenStringL(ptTemp));
}
DeleteToken (ptTemp);
if ((sRC == 0) && (pltNext->ucType != TTYPE_EOL))
sRC = ERR_EXTRA_CHARS;
(PBYTE)pltNext += (WORD) pltNext->ucLen;
}
*pltStart = pltNext;
return sRC;
}
//------------------------------------------------------------
// LocalLaunch - Launch a program
//------------------------------------------------------------
INT LocalLaunch (LPLINETOKEN *pltStart, INT sFunc){
char szProg[MAXLINELEN], chChar;
char *pszExt;
char *pszDefExt;
INT sRC, i, j;
LPLINETOKEN pltBegin;
PTOKEN ptName;
OFSTRUCT of;
BOOL bFound;
UINT wShowWin;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
pltBegin = *pltStart;
sRC = ResolveLine (pltStart, szProg, sizeof (szProg) - 5);
if (sRC) return sRC;
i = strcspn (szProg, " *+,/:;<>=|");
chChar = szProg[i];
szProg[i] = 0;
strupr (szProg);
bFound = FALSE;
ptName = FindToken (szProg, i);
if ((ptName != 0) && (ptName->ucType == TTYPE_INTCMD)) {
strcpy (szProg, getenv("COMSPEC"));
strcat (szProg, " /C ");
i = strlen (szProg);
sRC = ResolveLine (&pltBegin, szProg+i, sizeof (szProg) - i);
wShowWin = SW_SHOWMINIMIZED;
bFound = TRUE;
} else {
pszExt = strrchr (szProg, '.');
if ((pszExt == 0) || (pszExt < strrchr(szProg, '\\'))) {
//Make room on cmdline for ext
for (j = strlen (&szProg[i+1])+3; j > 0; j--)
szProg[i+j+4] = szProg[i+j];
szProg[i] = '.';
szProg[i+4] = 0;
pszDefExt = szProgExt;
bFound = FALSE;
while (*pszDefExt != 0) {
for (j = 0; j < 3; j++)
szProg[i+j+1] = *pszDefExt++;
if (OpenFile (szProg, &of, OF_EXIST) != HFILE_ERROR) {
bFound = TRUE;
break;
}
while ((*pszDefExt <= ' ') && (*pszDefExt != 0))
pszDefExt++;
}
szProg[i+4] = chChar;
} else {
szProg[i] = chChar;
bFound = TRUE;
}
wShowWin = SW_SHOWNORMAL;
}
if (bFound) {
sRC = WinExec (szProg, wShowWin);
if (sRC < 32)
sRC = ERR_LAUNCH_ERR - sRC;
else
sRC = 0;
} else
sRC = ERR_FOPEN_ERR - of.nErrCode;
*(PWORD)pltStart += (*pltStart)->ucLen;
return sRC;
// sRC = WinExec (szProg, SW_SHOWMINIMIZED);
}
//------------------------------------------------------------
// While - While loop statement
//------------------------------------------------------------
INT LocalWHILE (LPLINETOKEN *pltStart, INT sFunc){
LPLINETOKEN pltNext, pltSave;
INT sRC = 0;
pltNext = *pltStart;
if (pltNext->ucType == TTYPE_LINE)
(PBYTE) pltNext += pltNext->ucLen;
(PBYTE) pltNext += pltNext->ucLen;
if (!Eval2Num (&pltNext, sFunc, &sRC))
sFunc = FUNC_SKIP;
if (sRC) return sRC;
pltSave = pltNext;
if (pltNext->ucType == TTYPE_EOL) {
(PBYTE) pltNext += pltNext->ucLen;
sRC = ExecuteLine (&pltNext, sFunc);
} else {
sRC = Execute (&pltNext, sFunc);
if (pltNext->ucType == TTYPE_EOL)
(PBYTE) pltNext += pltNext->ucLen;
}
if (sRC == RC_END_OF_LOOP) {
sRC = 0;
pltNext = pltSave;
if (pltNext->ucType == TTYPE_EOL) {
(PBYTE) pltNext += pltNext->ucLen;
sRC = ExecuteLine (&pltNext, FUNC_SKIP);
} else {
sRC = Execute (&pltNext, FUNC_SKIP);
if (pltNext->ucType == TTYPE_EOL)
(PBYTE) pltNext += pltNext->ucLen;
}
*pltStart = pltNext;
}
if (sFunc & FUNC_SKIP)
*pltStart = pltNext;
return sRC;
}
//------------------------------------------------------------
// IF - If statement
//------------------------------------------------------------
INT LocalIF (LPLINETOKEN *pltStart, INT sFunc) {
LPLINETOKEN pltNext;
LONG lResult;
INT sRC = 0;
pltNext = *pltStart;
if (pltNext->ucType == TTYPE_LINE)
(PBYTE) pltNext += pltNext->ucLen;
(PBYTE) pltNext += pltNext->ucLen;
lResult = Eval2Num (&pltNext, sFunc, &sRC);
if (sRC) return sRC;
if (pltNext->ucType != TTYPE_EOL) { // If <then> clause on same line as IF
if (lResult) {
if (sFunc == FUNC_EXECUTE) {
sRC = Execute (&pltNext, sFunc);
if (pltNext->ucType == TTYPE_EOL)
(PBYTE) pltNext += pltNext->ucLen;
}
if (GetStatementType (pltNext) == TTYPE_THENELSE)
sRC = ExecuteLine (&pltNext, FUNC_SKIP);
} else
sRC = Execute (&pltNext, FUNC_SKIP);
} else { // If <then> clause on next line
(PBYTE) pltNext += pltNext->ucLen;
if (lResult) {
sRC = ExecuteLine (&pltNext, sFunc);
if (GetStatementType (pltNext) == TTYPE_THENELSE) {
sRC = ExecuteLine (&pltNext, FUNC_SKIP);
}
} else
sRC = ExecuteLine (&pltNext, FUNC_SKIP);
}
*pltStart = pltNext;
return sRC;
}
//------------------------------------------------------------
// Then/Else Statements
//------------------------------------------------------------
INT LocalThenElse (LPLINETOKEN *pltStart, INT sFunc) {
LPLINETOKEN pltNext;
INT sRC = 0;
pltNext = *pltStart;
if (pltNext->ucType == TTYPE_LINE)
(PBYTE) pltNext += pltNext->ucLen;
(PBYTE) pltNext += pltNext->ucLen;
if (pltNext->ucType != TTYPE_EOL) // More on same line
sRC = Execute (&pltNext, sFunc);
else { // Execute Next line
(PBYTE) pltNext += pltNext->ucLen;
sRC = ExecuteLine (&pltNext, sFunc);
}
*pltStart = pltNext;
return sRC;
}
//------------------------------------------------------------
// LocalDO - DO statement
//------------------------------------------------------------
INT LocalDO (LPLINETOKEN *pltStart, INT sFunc) {
LPLINETOKEN pltNext;
INT sRC = 0;
pltNext = *pltStart;
if (pltNext->ucType == TTYPE_LINE)
(PBYTE) pltNext += pltNext->ucLen;
(PBYTE) pltNext += pltNext->ucLen;
if (pltNext->ucType != TTYPE_EOL)
return ERR_EXTRA_CHARS;
(PBYTE) pltNext += pltNext->ucLen;
while (sRC == 0)
sRC = ExecuteLine (&pltNext, sFunc);
*pltStart = pltNext;
if (sRC != RC_END_OF_BLOCK)
return sRC;
return 0;
}
//------------------------------------------------------------
// LocalEND - END statement ends a block
//------------------------------------------------------------
INT LocalEND (LPLINETOKEN *pltStart, INT sFunc) {
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
if ((*pltStart)->ucType != TTYPE_EOL)
return ERR_EXTRA_CHARS;
*(PWORD)pltStart += (*pltStart)->ucLen;
return RC_END_OF_BLOCK;
}
//------------------------------------------------------------
// LocalRETURN - RETURN statement returns from a sub or
// function.
//------------------------------------------------------------
INT LocalRETURN (LPLINETOKEN *pltStart, INT sFunc) {
INT sRC = 0;
PTOKEN ptRetVal;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
ptRetVal = FindTokenByType (TTYPE_RETVAL);
ptRetVal->ucType = TTYPE_NUM;
if ((*pltStart)->ucType == TTYPE_EOL)
return RC_END_OF_SUB;
if (ptRetVal != 0) {
sRC = Eval (pltStart, ptRetVal, sFunc);
if (sRC)
return sRC;
}
if ((*pltStart)->ucType == TTYPE_EOL)
*(PWORD)pltStart += (*pltStart)->ucLen;
return RC_END_OF_SUB;
}
//------------------------------------------------------------
// LocalLEAVE - LEAVE statement exits from a loop
//
//------------------------------------------------------------
INT LocalLEAVE (LPLINETOKEN *pltStart, INT sFunc) {
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
if ((*pltStart)->ucType != TTYPE_EOL)
return ERR_EXTRA_CHARS;
else
return RC_END_OF_LOOP;
}
//------------------------------------------------------------
// LocalCMT2EOL- Comment statment, line ignored
// function.
//------------------------------------------------------------
INT LocalCMT2EOL (LPLINETOKEN *pltStart, INT sFunc) {
SkipLine (pltStart);
return 0;
}
//------------------------------------------------------------
// LocalEXIT - EXIT statement terminates program
//------------------------------------------------------------
INT LocalEXIT (LPLINETOKEN *pltStart, INT sFunc) {
INT sRC = 0;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
if ((*pltStart)->ucType == TTYPE_EOL)
return RC_END_OF_PROGRAM;
sFinalRC = (INT) Eval2Num (pltStart, sFunc, &sRC);
if (sRC)
return sRC;
else
return RC_END_OF_PROGRAM;
}
//------------------------------------------------------------
// LocalSAY - SAY statement
//------------------------------------------------------------
INT LocalSAY (LPLINETOKEN *pltStart, INT sFunc) {
char szOutput[MAXLINELEN];
INT sRC;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
sRC = ResolveLine (pltStart, szOutput, sizeof (szOutput));
if (sRC) return sRC;
WriteOutput (hMain, szOutput);
*(PWORD)pltStart += (*pltStart)->ucLen;
return sRC;
}
//------------------------------------------------------------
// LocalChDir - ChDir changes the current directory
//------------------------------------------------------------
INT LocalChDir (LPLINETOKEN *pltStart, INT sFunc) {
char szOutput[MAXLINELEN];
INT sRC;
if (sFunc & FUNC_SKIP) {
SkipLine (pltStart);
return 0;
}
if ((*pltStart)->ucType == TTYPE_LINE)
*(PWORD)pltStart += (*pltStart)->ucLen;
*(PWORD)pltStart += (*pltStart)->ucLen;
if ((*pltStart)->ucType != TTYPE_EOL) {
sRC = ResolveLine (pltStart, szOutput, sizeof (szOutput));
if (sRC) return sRC;
if (strlen (szOutput) < 128)
sRC = chdir (_fullpath(&szOutput[128], szOutput, sizeof (szOutput)-128));
else
sRC = chdir(szOutput);
if (sRC != 0)
sRC = ERR_PATH_NOT_FOUND;
} else {
getcwd (szOutput, sizeof (szOutput));
WriteOutput (hMain, szOutput);
sRC = 0;
}
*(PWORD)pltStart += (*pltStart)->ucLen;
return sRC;
}
//------------------------------------------------------------
// Operators
//------------------------------------------------------------
//------------------------------------------------------------
// LocalOpAdd - Adds two numbers
//------------------------------------------------------------
INT LocalOpAdd (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
LONG lTemp, lSrc, lDest;
INT sRC = 0;
if ((ptDest->ucType == TTYPE_STR) && (ptSrc->ucType != TTYPE_NUM)) {
sRC = AppendString (ptDest, GetTokenString (ptSrc));
} else {
lSrc = GetTokenVal (ptSrc);
lDest = GetTokenVal (ptDest);
lTemp = lSrc + lDest;
if (!((lDest ^ lSrc) & 0x80000000) &&
((lDest ^ lTemp) & 0x80000000))
sRC = ERR_OVERFLOW;
else
sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
}
return sRC;
}
//------------------------------------------------------------
// LocalOpSub - Subtracts two numbers
//------------------------------------------------------------
INT LocalOpSub (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
LONG lTemp, lSrc, lDest;
INT sRC = 0;
lSrc = GetTokenVal (ptSrc);
lDest = GetTokenVal (ptDest);
lTemp = lDest - lSrc;
if (((lDest ^ lSrc) & 0x80000000) &&
((lDest ^ lTemp) & 0x80000000))
sRC = ERR_OVERFLOW;
else
sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
return sRC;
}
//------------------------------------------------------------
// LocalOpMul - Multiplies two numbers
//------------------------------------------------------------
INT LocalOpMul (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
LONG lTemp, lSrc, lDest;
INT sRC = 0;
lSrc = GetTokenVal (ptSrc);
lDest = GetTokenVal (ptDest);
lTemp = lDest * lSrc;
if (((lDest ^ lSrc) & 0x80000000) && (lTemp >= 0) ||
!((lDest ^ lSrc) & 0x80000000) && (lTemp < 0))
sRC = ERR_OVERFLOW;
else
sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
return sRC;
}
//------------------------------------------------------------
// LocalOpDiv - Divides two numbers
//------------------------------------------------------------
INT LocalOpDiv (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
LONG lTemp;
lTemp = GetTokenVal (ptSrc);
if (lTemp == 0) return ERR_DIVIDE_BY_ZERO;
return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal(ptDest) / lTemp);
}
//------------------------------------------------------------
// LocalOpLThan - Less than comparision
//------------------------------------------------------------
INT LocalOpLThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (ptDest->dwData < ptSrc->dwData)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
ptDest->ucType = TTYPE_NUM;
return 0;
}
//------------------------------------------------------------
// LocalOpLEThan - Less or equal comparision
//------------------------------------------------------------
INT LocalOpLEThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (ptDest->dwData <= ptSrc->dwData)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
ptDest->ucType = TTYPE_NUM;
return 0;
}
//------------------------------------------------------------
// LocalOpGThan - Greater than comparision
//------------------------------------------------------------
INT LocalOpGThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (ptDest->dwData > ptSrc->dwData)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
ptDest->ucType = TTYPE_NUM;
return 0;
}
//------------------------------------------------------------
// LocalOpGEThan - Greater or equal comparision
//------------------------------------------------------------
INT LocalOpGEThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (ptDest->dwData >= ptSrc->dwData)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
ptDest->ucType = TTYPE_NUM;
return 0;
}
//------------------------------------------------------------
// LocalOpNotEqual - Not equal comparison
//------------------------------------------------------------
INT LocalOpNotEqual (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
INT sRC;
sRC = LocalOpCmp (pltLine, ptDest, ptSrc);
if (sRC == 0)
if (ptDest->dwData == MYFALSE)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
return sRC;
}
//------------------------------------------------------------
// LocalOpCmp - Equal comparison
//------------------------------------------------------------
INT LocalOpCmp (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (ptDest->ucType == ptSrc->ucType) {
if (ptDest->ucType == TTYPE_NUM) {
if (GetTokenVal (ptDest) == GetTokenVal(ptSrc))
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
} else if (ptDest->ucType == TTYPE_STR) {
if (lstrcmp (GetTokenStringL(ptDest),GetTokenStringL(ptSrc)) == 0)
ptDest->dwData = MYTRUE;
else
ptDest->dwData = MYFALSE;
} else
ptDest->dwData = MYFALSE;
} else
ptDest->dwData = MYFALSE;
ptDest->ucType = TTYPE_NUM;
return 0;
}
//------------------------------------------------------------
// LocalOpAND - Logical AND
//------------------------------------------------------------
INT LocalOpAND (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (GetTokenVal (ptSrc) && GetTokenVal (ptDest))
SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
else
SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
return 0;
}
//------------------------------------------------------------
// LocalOpANDBits - Bitwise AND
//------------------------------------------------------------
INT LocalOpANDBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) &
GetTokenVal (ptDest));
}
//------------------------------------------------------------
// LocalOpOR - Logical OR
//------------------------------------------------------------
INT LocalOpOR (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (GetTokenVal (ptSrc) || GetTokenVal (ptDest))
SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
else
SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
return 0;
}
//------------------------------------------------------------
// LocalOpORBits - Bitwise OR
//------------------------------------------------------------
INT LocalOpORBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) |
GetTokenVal (ptDest));
}
//------------------------------------------------------------
// LocalOpXOR - Logical XOR
//------------------------------------------------------------
INT LocalOpXOR (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if ( (GetTokenVal (ptSrc) && GetTokenVal (ptDest)) ||
!(GetTokenVal (ptSrc) && GetTokenVal (ptDest)))
SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
else
SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
return 0;
}
//------------------------------------------------------------
// LocalOpXORBits - Bitwise XOR
//------------------------------------------------------------
INT LocalOpXORBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) ^
GetTokenVal (ptDest));
}
//------------------------------------------------------------
// LocalOpNOT - Logical NOT
//------------------------------------------------------------
INT LocalOpNOT (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
if (GetTokenVal (ptSrc))
SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
else
SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
return 0;
}
//------------------------------------------------------------
// LocalOpNOTBits - Bitwise NOT
//------------------------------------------------------------
INT LocalOpNOTBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return SetToken (ptDest, TTYPE_NUM, 0, ~GetTokenVal (ptSrc));
}
//------------------------------------------------------------
// LocalOpOComma - Pauses current evaluation
//------------------------------------------------------------
INT LocalComma (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return 0;
}
//------------------------------------------------------------
// LocalOpOParen - Processes open paren character
//------------------------------------------------------------
INT LocalOpOPren (LPLINETOKEN *pltLine, PTOKEN ptDest) {
INT sRC;
sRC = Eval (pltLine, ptDest, FUNC_EXECUTE);
if (sRC) return sRC;
if ((*pltLine)->ucType != TTYPE_CPAREN)
return ERR_NO_CLOSE_PAREN;
sRC = (*pltLine)->ucLen;
*(PWORD)pltLine += sRC;
sRC = 0;
return sRC;
}
INT LocalOpCPren (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
return ERR_NO_OPEN_PAREN;
}
//------------------------------------------------------------
// Predefined functions
//------------------------------------------------------------
//------------------------------------------------------------
// LocalLENGTH - Predefined func that returns the length of a string
//------------------------------------------------------------
INT LocalLENGTH (LPLINETOKEN *pltLine, PTOKEN ptDest) {
PTOKEN ptArg;
ptArg = (PTOKEN) ptDest->dwData;
ptDest->dwData = 0;
if (ptDest->wData != 0)
return SetToken (ptDest, TTYPE_NUM, 0,
strlen (GetTokenString (ptArg-1)));
else
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
}
//------------------------------------------------------------
// LocalUPPER - Predefined func that converts a string to
// upper case.
//------------------------------------------------------------
INT LocalUPPER (LPLINETOKEN *pltLine, PTOKEN ptDest) {
PTOKEN ptArg;
ptArg = (PTOKEN) ptDest->dwData;
ptDest->dwData = 0;
if (ptDest->wData != 0)
return SetToken (ptDest, TTYPE_STR, 0,
(DWORD)(LPSTR)strupr(GetTokenString(ptArg-1)));
else
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
}
//------------------------------------------------------------
// LocalSUBSTR - Predefined func that returns a portion of a
// string.
//------------------------------------------------------------
INT LocalSUBSTR (LPLINETOKEN *pltLine, PTOKEN ptDest) {
INT sRC = 0;
UINT wStart = 0, wLen = 0xffff, wStrLen;
char chChar;
char *pszSrc;
PTOKEN ptArg;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData > 2)
wLen = (WORD) GetTokenVal (ptArg-3);
if (ptDest->wData > 1)
wStart = (WORD) GetTokenVal (ptArg-2);
pszSrc = (char *)(ptArg-1)->dwData;
wStrLen = strlen (pszSrc);
if (wStart > wStrLen)
ptDest->dwData = 0;
else {
pszSrc += wStart;
wStrLen = strlen (pszSrc);
if (wLen < wStrLen) {
chChar = *(pszSrc+wLen);
*(pszSrc+wLen) = 0;
}
ptDest->ucType = TTYPE_NUM;
sRC = SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)pszSrc);
if (wLen < wStrLen)
*(pszSrc+wLen) = chChar;
}
ptDest->ucType = TTYPE_STR;
ptDest->wData = 0;
return sRC;
}
//------------------------------------------------------------
// LocalARG - Predefined func that returns an a calling arg.
//------------------------------------------------------------
INT LocalARG (LPLINETOKEN *pltLine, PTOKEN ptDest) {
INT sRC;
PTOKEN ptArg, ptRetVal;
ptDest->ucType = TTYPE_NUM;
ptRetVal = FindTokenByType (TTYPE_RETVAL);
if (ptRetVal == 0)
return ERR_NOARGS;
if (ptDest->wData == 1) {
sRC = SetToken (ptDest, TTYPE_NUM, 0, (DWORD)ptRetVal->wData-1);
} else {
ptArg = (PTOKEN) ptDest->dwData;
if (ptRetVal->wData <= (UINT) GetTokenVal (ptArg-1)) {
sRC = SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
} else {
ptRetVal = (PTOKEN)ptRetVal->dwData;
ptRetVal -= GetTokenVal (ptArg-1);
sRC = SetToken (ptDest, ptRetVal->ucType, ptRetVal->wData, ptRetVal->dwData);
}
}
return sRC;
}
//------------------------------------------------------------
// LocalWAIT - Predefined func that stops execution for a
// number of milliseconds.
// Arg 1 - Number of milliseconds to wait
//------------------------------------------------------------
INT LocalWAIT (LPLINETOKEN *pltLine, PTOKEN ptDest) {
PTOKEN ptArg;
UINT wDelay;
if (bRunning == FALSE)
return 0;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData < 2)
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
wDelay = (UINT) GetTokenVal (ptArg-1);
if (wDelay == 0)
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
if (GetTokenVal (ptArg-1) > 0xffff)
wDelay = 0xffff;
hWaitTimer = SetTimer (hMain, WAITTIMER_ID, wDelay, 0);
if (hWaitTimer == 0)
return ERR_NO_TIMERS;
bHold = TRUE;
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYTRUE);
}
//------------------------------------------------------------
// Predefined functions useful in Windows
//------------------------------------------------------------
INT MyGetWindowText (HWND hWnd, LPSTR lpszOut, UINT wLen) {
return (INT) SendMessage (hWnd, WM_GETTEXT, wLen, (DWORD) lpszOut);
}
//------------------------------------------------------------
// WinActivate - Predefined func that sets the input focus to
// a window
// Arg 1 - Window title text
//------------------------------------------------------------
INT WinActivate (LPLINETOKEN *pltLine, PTOKEN ptDest) {
char szWinText[MAXLINELEN];
PTOKEN ptArg;
HWND hWndTarg, hWndT2;
ptArg = (PTOKEN) ptDest->dwData;
hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
if (hWndTarg != 0) {
hWndT2 = SetActiveWindow (hWndTarg);
MyGetWindowText (hWndT2, szWinText, sizeof szWinText);
return SetToken (ptDest, TTYPE_STR, 0,(DWORD)(LPSTR)szWinText);
} else
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
}
//------------------------------------------------------------
// WinSendKeys - Predefined func that sends keys to a window
// Arg 1 - Key string
//------------------------------------------------------------
INT WinSendKeys (LPLINETOKEN *pltLine, PTOKEN ptDest) {
PTOKEN ptArg;
char *pszKeyString;
INT sRC;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData > 1) {
pszKeyString = GetTokenString (ptArg-1);
sRC = StuffKeyString (&pszKeyString);
if (sRC) return sRC;
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYTRUE);
}
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
}
//------------------------------------------------------------
// WinGetActWin - Predefined func that returns the text of
// the active window.
// No Args
//------------------------------------------------------------
INT WinGetActWin (LPLINETOKEN *pltLine, PTOKEN ptDest) {
char szWinText[MAXLINELEN];
MyGetWindowText (GetActiveWindow(), szWinText, sizeof szWinText);
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
}
//------------------------------------------------------------
// WinGetNextWin - Predefined func that returns the text of
// the next window in the window list.
// Arg 1 - Window title text
//------------------------------------------------------------
INT WinGetNextWin (LPLINETOKEN *pltLine, PTOKEN ptDest) {
char szWinText[MAXLINELEN];
PTOKEN ptArg;
HWND hWndTarg;
ptArg = (PTOKEN) ptDest->dwData;
hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
hWndTarg = GetNextWindow(hWndTarg, GW_HWNDNEXT);
if (hWndTarg == 0)
return SetToken (ptDest, TTYPE_STR, 0, MYFALSE);
MyGetWindowText (hWndTarg, szWinText, sizeof szWinText);
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
}
//------------------------------------------------------------
// WinGetWinEXE - Predefined func that returns the name of the
// EXE that created a window
// Arg 1 - Window title text
//------------------------------------------------------------
INT WinGetWinEXE (LPLINETOKEN *pltLine, PTOKEN ptDest) {
char szWinText[MAXLINELEN];
PTOKEN ptArg;
HWND hWndTarg;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData > 1) {
hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
if (hWndTarg != 0) {
GetModuleFileName (GetWindowWord (hWndTarg, GWW_HINSTANCE),
szWinText, sizeof (szWinText));
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
}
}
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
}
//------------------------------------------------------------
// WinMsgBox - Predefined func that displays a message box
// on the screen.
// Arg 1 - Msg box title
// Arg 2 - Msg box text
// Arg 3 - Button/icon flags
//------------------------------------------------------------
INT WinMsgBox (LPLINETOKEN *pltLine, PTOKEN ptDest) {
PTOKEN ptArg;
INT sReturn;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData < 4)
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
sReturn = MessageBox (hMain, GetTokenString (ptArg-1),
GetTokenString (ptArg-2),
(UINT) GetTokenVal (ptArg-3));
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)sReturn);
}
//------------------------------------------------------------
// WinAskBox - Predefined func that displays a dialog box
// with an input field.
// Arg 1 - Win text
// Arg 2 - default answer
//------------------------------------------------------------
INT WinAskBox (LPLINETOKEN *pltLine, PTOKEN ptDest) {
char szWinText[MAXLINELEN];
PTOKEN ptArg;
INT sRet;
ptArg = (PTOKEN) ptDest->dwData;
if (ptDest->wData < 2)
return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
szWinText[0] = 0;
pszAskAns = szWinText;
sRet = MyDisplayDialog(hInst, "AskBox", hMain, (WNDPROC)AskDlgProc,
MAKELONG (GetTokenString (ptArg-1),
GetTokenString (ptArg-2)));
if (sRet)
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
else
return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
}
//------------------------------------------------------------
// WinTicks - Predefined func that returns the number of
// ticks since windows started.
// No Args
//------------------------------------------------------------
INT WinTicks (LPLINETOKEN *pltLine, PTOKEN ptDest) {
return SetToken (ptDest, TTYPE_NUM, 0, GetTickCount());
}